From c58e4367c7e604c2b647d6793af85a8001b4a8b3 Mon Sep 17 00:00:00 2001 From: Ahmad Reza Date: Fri, 14 Feb 2020 20:38:39 +0700 Subject: [PATCH 1/4] warn when using wrong implementation of getOptionSelected --- .../src/useAutocomplete/useAutocomplete.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js index c8b32008482e56..31d28463a2e9b3 100644 --- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js +++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js @@ -439,6 +439,19 @@ export default function useAutocomplete(props) { const item = newValue; newValue = Array.isArray(value) ? [...value] : []; + if (process.env.NODE_ENV !== 'production') { + const matches = newValue.filter(val => getOptionSelected(item, val)); + + if (matches.length > 1) { + console.error( + [ + 'Material-UI: the `getOptionSelected` method of useAutocomplete do not handle the arguments correctly.', + `The component expects a single value to match a given option but found ${matches}.`, + ].join('\n'), + ); + } + } + const itemIndex = findIndex(newValue, valueItem => getOptionSelected(item, valueItem)); if (itemIndex === -1) { From 063b38065e40b207e84808571dd06f15e81c1c17 Mon Sep 17 00:00:00 2001 From: Ahmad Reza Date: Sun, 16 Feb 2020 11:10:42 +0700 Subject: [PATCH 2/4] replace error message to reflect number of matches --- packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js index 31d28463a2e9b3..ff6cc8eeb74a2a 100644 --- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js +++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js @@ -446,7 +446,7 @@ export default function useAutocomplete(props) { console.error( [ 'Material-UI: the `getOptionSelected` method of useAutocomplete do not handle the arguments correctly.', - `The component expects a single value to match a given option but found ${matches}.`, + `The component expects a single value to match a given option but found ${matches.length} matches`, ].join('\n'), ); } From 45c4d783bab8e78a2a3af9c06ec20f241e6cd605 Mon Sep 17 00:00:00 2001 From: Ahmad Reza Date: Sun, 16 Feb 2020 11:15:48 +0700 Subject: [PATCH 3/4] prettier --- .../material-ui-lab/src/useAutocomplete/useAutocomplete.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js index ff6cc8eeb74a2a..9957ed76d7b23c 100644 --- a/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js +++ b/packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js @@ -446,7 +446,9 @@ export default function useAutocomplete(props) { console.error( [ 'Material-UI: the `getOptionSelected` method of useAutocomplete do not handle the arguments correctly.', - `The component expects a single value to match a given option but found ${matches.length} matches`, + `The component expects a single value to match a given option but found ${ + matches.length + } matches.`, ].join('\n'), ); } From 0bd00e08c06e875e4b702b12b8fe520d5ca014a6 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Thu, 20 Feb 2020 00:53:58 +0100 Subject: [PATCH 4/4] add test case --- .../src/Autocomplete/Autocomplete.test.js | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js index 1f9c5eec4286fa..bd9dc472f94d34 100644 --- a/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js +++ b/packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js @@ -736,6 +736,36 @@ describe('', () => { 'For the input option: "a", `getOptionLabel` returns: undefined', ); }); + + it('warn if getOptionSelected match multiple values for a given option', () => { + const value = [{ id: '10', text: 'One' }, { id: '20', text: 'Two' }]; + const options = [ + { id: '10', text: 'One' }, + { id: '20', text: 'Two' }, + { id: '30', text: 'Three' }, + ]; + + render( + option.text} + getOptionSelected={option => value.find(v => v.id === option.id)} + renderInput={params => } + />, + ); + + fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' }); + fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' }); + fireEvent.keyDown(document.activeElement, { key: 'Enter' }); + + expect(consoleErrorMock.callCount()).to.equal(1); // strict mode renders twice + expect(consoleErrorMock.args()[0][0]).to.include( + 'The component expects a single value to match a given option but found 2 matches.', + ); + }); }); describe('prop: options', () => {