From 108a1adb6ce5d056b9feaca6466dad8d4a930f57 Mon Sep 17 00:00:00 2001 From: Bernardo Smaniotto Date: Fri, 10 Nov 2017 13:53:20 -0200 Subject: [PATCH] Refactor SyntheticClipboardEvent tests to only use the public API (#11365) * Refactor SyntheticClipboardEvent tests to only use the public API * Replace local document creation by document body reset on each test case execution * Set up and tear down container separately * Tweak test assertion logic for clarity * Remove simulate abstraction and create events directly * Ensure the test covers IE8 behavior * Verify that persistence works --- .../__tests__/SyntheticClipboardEvent-test.js | 199 +++++++++++++++--- 1 file changed, 172 insertions(+), 27 deletions(-) diff --git a/packages/react-dom/src/events/__tests__/SyntheticClipboardEvent-test.js b/packages/react-dom/src/events/__tests__/SyntheticClipboardEvent-test.js index 436f1b1b2c38d3..4496e388bbe9dc 100644 --- a/packages/react-dom/src/events/__tests__/SyntheticClipboardEvent-test.js +++ b/packages/react-dom/src/events/__tests__/SyntheticClipboardEvent-test.js @@ -9,25 +9,33 @@ 'use strict'; -var SyntheticClipboardEvent; +var React; +var ReactDOM; describe('SyntheticClipboardEvent', () => { - var createEvent; + var simulateEvent; + var container; beforeEach(() => { - // TODO: can we express this test with only public API? - SyntheticClipboardEvent = require('../SyntheticClipboardEvent').default; - createEvent = function(nativeEvent) { - var target = require('../getEventTarget').default(nativeEvent); - return SyntheticClipboardEvent.getPooled({}, '', nativeEvent, target); - }; + React = require('react'); + ReactDOM = require('react-dom'); + + container = document.createElement('div'); + document.body.appendChild(container); + }); + + afterEach(() => { + document.body.removeChild(container); + container = null; }); describe('ClipboardEvent interface', () => { describe('clipboardData', () => { describe('when event has clipboardData', () => { it("returns event's clipboardData", () => { - // Mock clipboardData since native implementation doesn't have a constructor + var expectedCount = 0; + + // Mock clipboardData since jsdom implementation doesn't have a constructor var clipboardData = { dropEffect: null, effectAllowed: null, @@ -35,9 +43,36 @@ describe('SyntheticClipboardEvent', () => { items: null, types: null, }; - var clipboardEvent = createEvent({clipboardData: clipboardData}); + var eventHandler = event => { + expect(event.clipboardData).toBe(clipboardData); + expectedCount++; + }; + var div = ReactDOM.render( +
, + container, + ); + + var event; + event = document.createEvent('Event'); + event.initEvent('copy', true, true); + event.clipboardData = clipboardData; + div.dispatchEvent(event); + + event = document.createEvent('Event'); + event.initEvent('cut', true, true); + event.clipboardData = clipboardData; + div.dispatchEvent(event); - expect(clipboardEvent.clipboardData).toBe(clipboardData); + event = document.createEvent('Event'); + event.initEvent('paste', true, true); + event.clipboardData = clipboardData; + div.dispatchEvent(event); + + expect(expectedCount).toBe(3); }); }); }); @@ -45,32 +80,142 @@ describe('SyntheticClipboardEvent', () => { describe('EventInterface', () => { it('normalizes properties from the Event interface', () => { - var target = document.createElement('div'); - var syntheticEvent = createEvent({srcElement: target}); + var expectedCount = 0; + var div; + + var eventHandler = type => event => { + expect(event.target).toBe(div); + expect(event.type).toBe(type); + expectedCount++; + }; + + div = ReactDOM.render( +
, + container, + ); + + var event; + event = document.createEvent('Event'); + event.initEvent('copy', true, true); + // Emulate IE8 + Object.defineProperty(event, 'target', { + get() {}, + }); + Object.defineProperty(event, 'srcElement', { + get() { + return div; + }, + }); + div.dispatchEvent(event); + + event = document.createEvent('Event'); + event.initEvent('cut', true, true); + // Emulate IE8 + Object.defineProperty(event, 'target', { + get() {}, + }); + Object.defineProperty(event, 'srcElement', { + get() { + return div; + }, + }); + div.dispatchEvent(event); - expect(syntheticEvent.target).toBe(target); - expect(syntheticEvent.type).toBe(undefined); + event = document.createEvent('Event'); + event.initEvent('paste', true, true); + // Emulate IE8 + Object.defineProperty(event, 'target', { + get() {}, + }); + Object.defineProperty(event, 'srcElement', { + get() { + return div; + }, + }); + div.dispatchEvent(event); + + expect(expectedCount).toBe(3); }); it('is able to `preventDefault` and `stopPropagation`', () => { - var nativeEvent = {}; - var syntheticEvent = createEvent(nativeEvent); + var expectedCount = 0; + + var eventHandler = event => { + expect(event.isDefaultPrevented()).toBe(false); + event.preventDefault(); + expect(event.isDefaultPrevented()).toBe(true); + expect(event.isPropagationStopped()).toBe(false); + event.stopPropagation(); + expect(event.isPropagationStopped()).toBe(true); + expectedCount++; + }; + + var div = ReactDOM.render( +
, + container, + ); - expect(syntheticEvent.isDefaultPrevented()).toBe(false); - syntheticEvent.preventDefault(); - expect(syntheticEvent.isDefaultPrevented()).toBe(true); + var event; + event = document.createEvent('Event'); + event.initEvent('copy', true, true); + div.dispatchEvent(event); - expect(syntheticEvent.isPropagationStopped()).toBe(false); - syntheticEvent.stopPropagation(); - expect(syntheticEvent.isPropagationStopped()).toBe(true); + event = document.createEvent('Event'); + event.initEvent('cut', true, true); + div.dispatchEvent(event); + + event = document.createEvent('Event'); + event.initEvent('paste', true, true); + div.dispatchEvent(event); + + expect(expectedCount).toBe(3); }); it('is able to `persist`', () => { - var syntheticEvent = createEvent({}); + var expectedCount = 0; + + const persistentEvents = []; + var eventHandler = event => { + expect(event.isPersistent()).toBe(false); + event.persist(); + expect(event.isPersistent()).toBe(true); + persistentEvents.push(event); + }; + + var div = ReactDOM.render( +
, + container, + ); + + var event; + event = document.createEvent('Event'); + event.initEvent('copy', true, true); + div.dispatchEvent(event); + + event = document.createEvent('Event'); + event.initEvent('cut', true, true); + div.dispatchEvent(event); + + event = document.createEvent('Event'); + event.initEvent('paste', true, true); + div.dispatchEvent(event); - expect(syntheticEvent.isPersistent()).toBe(false); - syntheticEvent.persist(); - expect(syntheticEvent.isPersistent()).toBe(true); + expect(persistentEvents.length).toBe(3); + expect(persistentEvents[0].type).toBe('copy'); + expect(persistentEvents[1].type).toBe('cut'); + expect(persistentEvents[2].type).toBe('paste'); }); }); });