Skip to content

Commit

Permalink
feat(widgets): add $$type to widgets definition (#3960)
Browse files Browse the repository at this point in the history
Adding a type to the `index` widget is necessary to filter it out from the list of the widgets. This is needed to implement the "reset page" behavior to get all the `index`-type children and reset their own page.

I took this opportunity to add a type to all widgets for debugging purpose.

The `$$type` property is not required in TypeScript because once we expose the widget interface, users might not need to mark them.
  • Loading branch information
francoischalifour authored and Haroenv committed Oct 23, 2019
1 parent ec30168 commit 344d1b7
Show file tree
Hide file tree
Showing 49 changed files with 495 additions and 2 deletions.
18 changes: 18 additions & 0 deletions src/connectors/autocomplete/__tests__/connectAutocomplete-test.js
Expand Up @@ -15,6 +15,24 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/autocomplet
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customAutocomplete = connectAutocomplete(render, unmount);
const widget = customAutocomplete({});

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.autocomplete',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
})
);
});

it('renders during init and render', () => {
const renderFn = jest.fn();
const makeWidget = connectAutocomplete(renderFn);
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/autocomplete/connectAutocomplete.js
Expand Up @@ -56,6 +56,8 @@ export default function connectAutocomplete(renderFn, unmountFn = noop) {
}

return {
$$type: 'ais.autocomplete',

getConfiguration() {
const parameters = {
query: '',
Expand Down
18 changes: 18 additions & 0 deletions src/connectors/breadcrumb/__tests__/connectBreadcrumb-test.js
Expand Up @@ -39,6 +39,24 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/breadcrumb/
});
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customBreadcrumb = connectBreadcrumb(render, unmount);
const widget = customBreadcrumb({ attributes: ['category'] });

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.breadcrumb',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
})
);
});

describe('getConfiguration', () => {
beforeEach(() => {
warning.cache = {};
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/breadcrumb/connectBreadcrumb.js
Expand Up @@ -64,6 +64,8 @@ export default function connectBreadcrumb(renderFn, unmountFn = noop) {
const [hierarchicalFacetName] = attributes;

return {
$$type: 'ais.breadcrumb',

getConfiguration: currentConfiguration => {
if (currentConfiguration.hierarchicalFacets) {
const isFacetSet = find(
Expand Down
Expand Up @@ -27,6 +27,23 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/clear-refin
See documentation: https://www.algolia.com/doc/api-reference/widgets/clear-refinements/js/#connector"
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customClearRefinements = connectClearRefinements(render, unmount);
const widget = customClearRefinements({});

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.clearRefinements',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
})
);
});
});

describe('Lifecycle', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/clear-refinements/connectClearRefinements.js
Expand Up @@ -87,6 +87,8 @@ export default function connectClearRefinements(renderFn, unmountFn = noop) {
} = widgetParams;

return {
$$type: 'ais.clearRefinements',

init({ helper, instantSearchInstance, createURL }) {
const attributesToClear = getAttributesToClear({
helper,
Expand Down
18 changes: 18 additions & 0 deletions src/connectors/configure/__tests__/connectConfigure-test.js
Expand Up @@ -53,6 +53,24 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/configure/j
});
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customConfigure = connectConfigure(render, unmount);
const widget = customConfigure({ searchParameters: {} });

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.configure',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
})
);
});

it('should apply searchParameters', () => {
const makeWidget = connectConfigure();
const widget = makeWidget({ searchParameters: { analytics: true } });
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/configure/connectConfigure.js
Expand Up @@ -39,6 +39,8 @@ export default function connectConfigure(renderFn = noop, unmountFn = noop) {
}

return {
$$type: 'ais.configure',

getConfiguration() {
return widgetParams.searchParameters;
},
Expand Down
Expand Up @@ -17,6 +17,26 @@ describe('connectCurrentRefinements', () => {
See documentation: https://www.algolia.com/doc/api-reference/widgets/current-refinements/js/#connector"
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customCurrentRefinements = connectCurrentRefinements(
render,
unmount
);
const widget = customCurrentRefinements({});

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.currentRefinements',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
})
);
});
});

describe('Lifecycle', () => {
Expand Down
Expand Up @@ -120,6 +120,8 @@ export default function connectCurrentRefinements(renderFn, unmountFn = noop) {
} = widgetParams;

return {
$$type: 'ais.currentRefinements',

init({ helper, createURL, instantSearchInstance }) {
const items = transformItems(
getFilteredRefinements({
Expand Down
3 changes: 2 additions & 1 deletion src/connectors/geo-search/__tests__/connectGeoSearch-test.js
Expand Up @@ -52,9 +52,10 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/geo-search/
const unmount = jest.fn();

const customGeoSearch = connectGeoSearch(render, unmount);
const widget = customGeoSearch();
const widget = customGeoSearch({});

expect(widget).toEqual({
$$type: 'ais.geoSearch',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
Expand Down
3 changes: 3 additions & 0 deletions src/connectors/geo-search/connectGeoSearch.js
Expand Up @@ -332,7 +332,10 @@ http://community.algolia.com/instantsearch.js/migration-guide
};

return {
$$type: 'ais.geoSearch',

init,

render,

dispose({ state }) {
Expand Down
Expand Up @@ -46,6 +46,26 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hierarchica
See documentation: https://www.algolia.com/doc/api-reference/widgets/hierarchical-menu/js/#connector"
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customHierarchicalMenu = connectHierarchicalMenu(render, unmount);
const widget = customHierarchicalMenu({ attributes: ['category'] });

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.hierarchicalMenu',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
getWidgetState: expect.any(Function),
getWidgetSearchParameters: expect.any(Function),
})
);
});
});

describe('getConfiguration', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/hierarchical-menu/connectHierarchicalMenu.js
Expand Up @@ -94,6 +94,8 @@ export default function connectHierarchicalMenu(renderFn, unmountFn = noop) {
const [hierarchicalFacetName] = attributes;

return {
$$type: 'ais.hierarchicalMenu',

isShowingMore: false,

// Provide the same function to the `renderFn` so that way the user
Expand Down
20 changes: 20 additions & 0 deletions src/connectors/hits-per-page/__tests__/connectHitsPerPage-test.js
Expand Up @@ -32,6 +32,26 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits-per-pa
See documentation: https://www.algolia.com/doc/api-reference/widgets/hits-per-page/js/#connector"
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customHitsPerPage = connectHitsPerPage(render, unmount);
const widget = customHitsPerPage({ items: [] });

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.hitsPerPage',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
getWidgetState: expect.any(Function),
getWidgetSearchParameters: expect.any(Function),
})
);
});
});

it('Renders during init and render', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/hits-per-page/connectHitsPerPage.js
Expand Up @@ -118,6 +118,8 @@ export default function connectHitsPerPage(renderFn, unmountFn = noop) {
const defaultValue = find(userItems, item => item.default === true);

return {
$$type: 'ais.hitsPerPage',

getConfiguration() {
return defaultValues.length > 0
? { hitsPerPage: defaultValues[0].value }
Expand Down
18 changes: 18 additions & 0 deletions src/connectors/hits/__tests__/connectHits-test.js
Expand Up @@ -20,6 +20,24 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/hits/js/#co
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customHits = connectHits(render, unmount);
const widget = customHits({});

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.hits',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
})
);
});

it('Renders during init and render', () => {
const renderFn = jest.fn();
const makeWidget = connectHits(renderFn);
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/hits/connectHits.js
Expand Up @@ -58,6 +58,8 @@ export default function connectHits(renderFn, unmountFn = noop) {
const { escapeHTML = true, transformItems = items => items } = widgetParams;

return {
$$type: 'ais.hits',

getConfiguration() {
return escapeHTML ? TAG_PLACEHOLDER : undefined;
},
Expand Down
20 changes: 20 additions & 0 deletions src/connectors/infinite-hits/__tests__/connectInfiniteHits-test.ts
Expand Up @@ -32,6 +32,26 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/infinite-hi
`);
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customInfiniteHits = connectInfiniteHits(render, unmount);
const widget = customInfiniteHits({});

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.infiniteHits',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
getWidgetState: expect.any(Function),
getWidgetSearchParameters: expect.any(Function),
})
);
});

it('Renders during init and render', () => {
const renderFn = jest.fn();
const instantSearchInstance = createInstantSearch();
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/infinite-hits/connectInfiniteHits.ts
Expand Up @@ -86,6 +86,8 @@ const connectInfiniteHits: InfiniteHitsConnector = (
};

return {
$$type: 'ais.infiniteHits',

getConfiguration() {
const parameters = {
page: 0,
Expand Down
22 changes: 21 additions & 1 deletion src/connectors/menu/__tests__/connectMenu-test.js
Expand Up @@ -15,7 +15,7 @@ describe('connectMenu', () => {
});

describe('Usage', () => {
it('throws with render function', () => {
it('throws without render function', () => {
expect(() => {
connectMenu()({});
}).toThrowErrorMatchingInlineSnapshot(`
Expand Down Expand Up @@ -56,6 +56,26 @@ See documentation: https://www.algolia.com/doc/api-reference/widgets/menu/js/#co
});
});

it('is a widget', () => {
const render = jest.fn();
const unmount = jest.fn();

const customMenu = connectMenu(render, unmount);
const widget = customMenu({ attribute: 'facet' });

expect(widget).toEqual(
expect.objectContaining({
$$type: 'ais.menu',
init: expect.any(Function),
render: expect.any(Function),
dispose: expect.any(Function),
getConfiguration: expect.any(Function),
getWidgetState: expect.any(Function),
getWidgetSearchParameters: expect.any(Function),
})
);
});

describe('options configuring the helper', () => {
it('`attribute`', () => {
const widget = makeWidget({
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/menu/connectMenu.js
Expand Up @@ -115,6 +115,8 @@ export default function connectMenu(renderFn, unmountFn = noop) {
}

return {
$$type: 'ais.menu',

isShowingMore: false,

// Provide the same function to the `renderFn` so that way the user
Expand Down

0 comments on commit 344d1b7

Please sign in to comment.