[gold] Extract out eventPromise() from corpus-selector-sk_test.js into test_util.js.
Bug: skia:9525
Change-Id: I278a64a33aab35806ff27b6ef2a0a60d1134c9cd
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/255141
Commit-Queue: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/golden/modules/corpus-selector-sk/corpus-selector-sk_test.js b/golden/modules/corpus-selector-sk/corpus-selector-sk_test.js
index 7239b97..3adae1c 100644
--- a/golden/modules/corpus-selector-sk/corpus-selector-sk_test.js
+++ b/golden/modules/corpus-selector-sk/corpus-selector-sk_test.js
@@ -1,6 +1,7 @@
import './index.js';
import { $, $$ } from 'common-sk/modules/dom';
import { deepCopy } from 'common-sk/modules/object';
+import { eventPromise } from '../test_util';
import { fetchMock } from 'fetch-mock';
import { trstatus } from './test_data';
@@ -249,53 +250,3 @@
expect(corporaLiText(corpusSelectorSk)).to.be.empty;
})
});
-
-// TODO(lovisolo): Move to test_util.js.
-// Returns a promise that will resolve when the given event is caught at the
-// document's body element, or reject if the event isn't caught within the given
-// amount of time.
-//
-// Set timeoutMillis = 0 to skip call to setTimeout(). This is necessary on
-// tests that simulate the passing of time with sinon.useFakeTimers(), which
-// could trigger the timeout before the promise has a chance to catch the event.
-//
-// Sample usage:
-//
-// // Code under test.
-// function doSomethingThatTriggersCustomEvent() {
-// ...
-// this.dispatchEvent(
-// new CustomEvent('my-event', {detail: {foo: 'bar'}, bubbles: true});
-// }
-//
-// // Test.
-// it('should trigger a custom event', async () => {
-// const myEvent = eventPromise('my-event');
-// doSomethingThatTriggersCustomEvent();
-// const ev = await myEvent;
-// expect(ev.detail.foo).to.equal('bar');
-// });
-function eventPromise(event, timeoutMillis = 5000) {
- // The executor function passed as a constructor argument to the Promise
- // object is executed immediately. This guarantees that the event handler
- // is added to document.body before returning.
- return new Promise((resolve, reject) => {
- let timeout;
- const handler = (e) => {
- document.body.removeEventListener(event, handler);
- clearTimeout(timeout);
- resolve(e);
- };
- // Skip setTimeout() call with timeoutMillis = 0. Useful when faking time in
- // tests with sinon.useFakeTimers(). See
- // https://sinonjs.org/releases/v7.5.0/fake-timers/.
- if (timeoutMillis !== 0) {
- timeout = setTimeout(() => {
- document.body.removeEventListener(event, handler);
- reject(new Error(`timed out after ${timeoutMillis} ms ` +
- `while waiting to catch event "${event}"`));
- }, timeoutMillis);
- }
- document.body.addEventListener(event, handler);
- });
-}
diff --git a/golden/modules/test_util.js b/golden/modules/test_util.js
index d4fbfef..504590e 100644
--- a/golden/modules/test_util.js
+++ b/golden/modules/test_util.js
@@ -23,4 +23,60 @@
if (calls.length) {
console.warn('unmatched POSTS', calls);
}
-}
\ No newline at end of file
+}
+
+/**
+ * Returns a promise that will resolve when the given event is caught at the
+ * document's body element, or reject if the event isn't caught within the given
+ * amount of time.
+ *
+ * Set timeoutMillis = 0 to skip call to setTimeout(). This is necessary on
+ * tests that simulate the passing of time with sinon.useFakeTimers(), which
+ * could trigger the timeout before the promise has a chance to catch the event.
+ *
+ * Sample usage:
+ *
+ * // Code under test.
+ * function doSomethingThatTriggersCustomEvent() {
+ * ...
+ * this.dispatchEvent(
+ * new CustomEvent('my-event', {detail: {foo: 'bar'}, bubbles: true});
+ * }
+ *
+ * // Test.
+ * it('should trigger a custom event', async () => {
+ * const myEvent = eventPromise('my-event');
+ * doSomethingThatTriggersCustomEvent();
+ * const ev = await myEvent;
+ * expect(ev.detail.foo).to.equal('bar');
+ * });
+ *
+ * @param event {string} Name of event to catch.
+ * @param timeoutMillis {number} How long to wait for the event before rejecting
+ * the returned promise.
+ * @return {Promise} A promise that will resolve to the caught event.
+ */
+export function eventPromise(event, timeoutMillis = 5000) {
+ // The executor function passed as a constructor argument to the Promise
+ // object is executed immediately. This guarantees that the event handler
+ // is added to document.body before returning.
+ return new Promise((resolve, reject) => {
+ let timeout;
+ const handler = (e) => {
+ document.body.removeEventListener(event, handler);
+ clearTimeout(timeout);
+ resolve(e);
+ };
+ // Skip setTimeout() call with timeoutMillis = 0. Useful when faking time in
+ // tests with sinon.useFakeTimers(). See
+ // https://sinonjs.org/releases/v7.5.0/fake-timers/.
+ if (timeoutMillis !== 0) {
+ timeout = setTimeout(() => {
+ document.body.removeEventListener(event, handler);
+ reject(new Error(`timed out after ${timeoutMillis} ms ` +
+ `while waiting to catch event "${event}"`));
+ }, timeoutMillis);
+ }
+ document.body.addEventListener(event, handler);
+ });
+}
diff --git a/golden/modules/test_util_test.js b/golden/modules/test_util_test.js
new file mode 100644
index 0000000..00e0686
--- /dev/null
+++ b/golden/modules/test_util_test.js
@@ -0,0 +1,48 @@
+import {eventPromise} from './test_util';
+
+describe('test utilities', () => {
+
+ describe('eventPromise', () => {
+ let el; // Element that we'll dispatch custom events from.
+ let clock;
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ document.body.appendChild(el);
+ clock = sinon.useFakeTimers();
+ });
+
+ afterEach(() => {
+ document.body.removeChild(el);
+ clock.restore();
+ });
+
+ it('resolves when event is caught', async () => {
+ const hello = eventPromise('hello');
+ el.dispatchEvent(new CustomEvent('hello', {bubbles: true, detail: 'hi'}));
+ const ev = await hello;
+ expect(ev.detail).to.equal('hi');
+ });
+
+ it('times out if event is not caught', async () => {
+ const hello = eventPromise('hello', 5000);
+ el.dispatchEvent(new CustomEvent('bye', {bubbles: true}));
+ clock.tick(10000);
+ try {
+ await hello;
+ expect.fail('promise should not have resolved');
+ } catch(error) {
+ expect(error.message).to.equal(
+ 'timed out after 5000 ms while waiting to catch event "hello"');
+ }
+ });
+
+ it('never times out if timeoutMillis=0', async () => {
+ const hello = eventPromise('hello', 0);
+ clock.tick(Number.MAX_SAFE_INTEGER);
+ el.dispatchEvent(new CustomEvent('hello', {bubbles: true, detail: 'hi'}));
+ const ev = await hello;
+ expect(ev.detail).to.equal('hi');
+ });
+ });
+});
\ No newline at end of file