Skip to content

Commit

Permalink
fix(widgets): replace setImmediate use with Promise use when update i…
Browse files Browse the repository at this point in the history
…s needed (#1811)

Default to setTimeout if Promise is undefined.

History:
1. process.nextTicks wasn't available on react-native
2. setImmediate is not available on Meteor (and maybe others..)
  • Loading branch information
mthuret authored and bobylito committed Jan 9, 2017
1 parent 58df900 commit 17e2497
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,19 @@ describe('createInstantSearchManager', () => {
algoliaClient: client,
});

const widgetIDsT0 = ism.getWidgetsIds().sort();
expect(widgetIDsT0).toEqual([]);

ism.widgetsManager.registerWidget({getMetadata: () => ({id: 'a'})});
ism.widgetsManager.registerWidget({getMetadata: () => ({id: 'b'})});
ism.widgetsManager.registerWidget({getMetadata: () => ({id: 'c'})});
ism.widgetsManager.registerWidget({getMetadata: () => ({id: 'd'})});

const widgetIDsT0 = ism.getWidgetsIds().sort();
expect(widgetIDsT0).toEqual([]);

jest.runAllTimers();
ism.widgetsManager.registerWidget({getMetadata: () => ({id: 'd'})});

const widgetIDsT1 = ism.getWidgetsIds().sort();
expect(widgetIDsT1).toEqual(['a', 'b', 'c', 'd']);
return Promise.resolve().then(() => {
const widgetIDsT1 = ism.getWidgetsIds().sort();
expect(widgetIDsT1).toEqual(['a', 'b', 'c', 'd']);
});
});
});
});
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {defer} from './utils';

export default function createWidgetsManager(onWidgetsUpdate) {
const widgets = [];
// Is an update scheduled?
Expand All @@ -10,7 +12,7 @@ export default function createWidgetsManager(onWidgetsUpdate) {
return;
}
scheduled = true;
setImmediate(() => {
defer(() => {
scheduled = false;
onWidgetsUpdate();
});
Expand Down
18 changes: 6 additions & 12 deletions packages/react-instantsearch/src/core/createWidgetsManager.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,23 @@ describe('createWidgetsManager', () => {
});

it('schedules an update', () => {
jest.useFakeTimers();
const onUpdate = jest.fn();
const wm = createWidgetsManager(onUpdate);
jest.runAllImmediates();
wm.registerWidget({});
expect(onUpdate.mock.calls.length).toBe(0);
jest.runAllImmediates();
expect(onUpdate.mock.calls.length).toBe(1);
jest.useRealTimers();
return Promise.resolve().then(() => {
expect(onUpdate.mock.calls.length).toBe(1);
});
});
});

describe('update', () => {
it('schedules an update', () => {
jest.useFakeTimers();
const onUpdate = jest.fn();
const wm = createWidgetsManager(onUpdate);
jest.runAllImmediates();
wm.update();
expect(onUpdate.mock.calls.length).toBe(0);
jest.runAllImmediates();
expect(onUpdate.mock.calls.length).toBe(1);
jest.useRealTimers();
return Promise.resolve().then(() => {
expect(onUpdate.mock.calls.length).toBe(1);
});
});
});
});
3 changes: 3 additions & 0 deletions packages/react-instantsearch/src/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,6 @@ export function assertFacetDefined(searchParameters, searchResults, facet) {
export function getDisplayName(Component) {
return Component.displayName || Component.name || 'UnknownComponent';
}

const resolved = Promise.resolve();
export const defer = f => { resolved.then(f); };
19 changes: 18 additions & 1 deletion packages/react-instantsearch/src/core/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
capitalize,
assertFacetDefined,
getDisplayName,
defer,
} from './utils';

import {SearchParameters, SearchResults} from 'algoliasearch-helper';
Expand Down Expand Up @@ -83,7 +84,9 @@ describe('utils', () => {

it('gets the right displayName from React.createClass', () => {
const SuperComponent = React.createClass({
render() { return null; },
render() {
return null;
},
displayName: 'SuperComponent',
});

Expand All @@ -94,4 +97,18 @@ describe('utils', () => {
expect(getDisplayName(() => null)).toBe('UnknownComponent');
});
});
describe('defer', () => {
it('calling a function asynchronously, should be done as soon as possible.', () => {
let count = 0;

defer(() => {
count = 1;
});

return Promise.resolve().then(() => {
expect(count).toEqual(1);
});
});
});
});

0 comments on commit 17e2497

Please sign in to comment.