From 603da9b4ea489ab9ea479f84c0bfdd069145cd56 Mon Sep 17 00:00:00 2001 From: Michael Lange Date: Mon, 23 Apr 2018 16:18:06 -0700 Subject: [PATCH] Test coverage for the changes to the searchable mixin --- ui/app/mixins/searchable.js | 64 ++++++++----- ui/tests/unit/mixins/searchable-test.js | 121 ++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 24 deletions(-) diff --git a/ui/app/mixins/searchable.js b/ui/app/mixins/searchable.js index 2f94d398d..f3df9e134 100644 --- a/ui/app/mixins/searchable.js +++ b/ui/app/mixins/searchable.js @@ -11,6 +11,12 @@ import Fuse from 'npm:fuse.js'; Properties to override: - searchTerm: the string to use as a query - searchProps: the props on each object to search + -- exactMatchSearchProps: the props for exact search when props are different per search type + -- regexSearchProps: the props for regex search when props are different per search type + -- fuzzySearchProps: the props for fuzzy search when props are different per search type + - exactMatchEnabled: (true) disable to not use the exact match search type + - fuzzySearchEnabled: (false) enable to use the fuzzy search type + - regexEnabled: (true) disable to disable the regex search type - listToSearch: the list of objects to search Properties provided: @@ -23,7 +29,7 @@ export default Mixin.create({ searchProps: null, exactMatchSearchProps: reads('searchProps'), regexSearchProps: reads('searchProps'), - fuzzySearchProps: reads('searchprops'), + fuzzySearchProps: reads('searchProps'), // Three search modes exactMatchEnabled: true, @@ -47,31 +53,41 @@ export default Mixin.create({ }); }), - listSearched: computed('searchTerm', 'listToSearch.[]', 'searchProps.[]', function() { - const searchTerm = this.get('searchTerm').trim(); - if (searchTerm && searchTerm.length) { - const results = []; - if (this.get('exactMatchEnabled')) { - results.push( - ...exactMatchSearch( - searchTerm, - this.get('listToSearch'), - this.get('exactMatchSearchProps') - ) - ); + listSearched: computed( + 'searchTerm', + 'listToSearch.[]', + 'exactMatchEnabled', + 'fuzzySearchEnabled', + 'regexEnabled', + 'exactMatchSearchProps.[]', + 'fuzzySearchProps.[]', + 'regexSearchProps.[]', + function() { + const searchTerm = this.get('searchTerm').trim(); + if (searchTerm && searchTerm.length) { + const results = []; + if (this.get('exactMatchEnabled')) { + results.push( + ...exactMatchSearch( + searchTerm, + this.get('listToSearch'), + this.get('exactMatchSearchProps') + ) + ); + } + if (this.get('fuzzySearchEnabled')) { + results.push(...this.get('fuse').search(searchTerm)); + } + if (this.get('regexEnabled')) { + results.push( + ...regexSearch(searchTerm, this.get('listToSearch'), this.get('regexSearchProps')) + ); + } + return results.uniq(); } - if (this.get('fuzzySearchEnabled')) { - results.push(...this.get('fuse').search(searchTerm)); - } - if (this.get('regexEnabled')) { - results.push( - ...regexSearch(searchTerm, this.get('listToSearch'), this.get('regexSearchProps')) - ); - } - return results.uniq(); + return this.get('listToSearch'); } - return this.get('listToSearch'); - }), + ), }); function exactMatchSearch(term, list, keys) { diff --git a/ui/tests/unit/mixins/searchable-test.js b/ui/tests/unit/mixins/searchable-test.js index 4478913a2..10396e749 100644 --- a/ui/tests/unit/mixins/searchable-test.js +++ b/ui/tests/unit/mixins/searchable-test.js @@ -55,3 +55,124 @@ test('the searchable mixin only searches the declared search props', function(as 'Only USA matched, since continent is not a search prop' ); }); + +test('the fuzzy search mode is off by default', function(assert) { + const subject = this.subject(); + subject.set('source', [ + { id: '1', name: 'United States of America', continent: 'North America' }, + { id: '2', name: 'Canada', continent: 'North America' }, + { id: '3', name: 'Mexico', continent: 'North America' }, + ]); + + subject.set('searchTerm', 'Ameerica'); + assert.deepEqual( + subject.get('listSearched'), + [], + 'Nothing is matched since America is spelled incorrectly' + ); +}); + +test('the fuzzy search mode can be enabled', function(assert) { + const subject = this.subject(); + subject.set('source', [ + { id: '1', name: 'United States of America', continent: 'North America' }, + { id: '2', name: 'Canada', continent: 'North America' }, + { id: '3', name: 'Mexico', continent: 'North America' }, + ]); + + subject.set('fuzzySearchEnabled', true); + subject.set('searchTerm', 'Ameerica'); + assert.deepEqual( + subject.get('listSearched'), + [{ id: '1', name: 'United States of America', continent: 'North America' }], + 'America is matched due to fuzzy matching' + ); +}); + +test('the exact match search mode can be disabled', function(assert) { + const subject = this.subject(); + subject.set('source', [ + { id: '1', name: 'United States of America', continent: 'North America' }, + { id: '2', name: 'Canada', continent: 'North America' }, + { id: '3', name: 'Mexico', continent: 'North America' }, + ]); + + subject.set('regexSearchProps', []); + subject.set('searchTerm', 'Mexico'); + + assert.deepEqual( + subject.get('listSearched'), + [{ id: '3', name: 'Mexico', continent: 'North America' }], + 'Mexico is matched exactly' + ); + + subject.set('exactMatchEnabled', false); + + assert.deepEqual( + subject.get('listSearched'), + [], + 'Nothing is matched now that exactMatch is disabled' + ); +}); + +test('the regex search mode can be disabled', function(assert) { + const subject = this.subject(); + subject.set('source', [ + { id: '1', name: 'United States of America', continent: 'North America' }, + { id: '2', name: 'Canada', continent: 'North America' }, + { id: '3', name: 'Mexico', continent: 'North America' }, + ]); + + subject.set('searchTerm', '^.{6}$'); + assert.deepEqual( + subject.get('listSearched'), + [ + { id: '2', name: 'Canada', continent: 'North America' }, + { id: '3', name: 'Mexico', continent: 'North America' }, + ], + 'Canada and Mexico meet the regex criteria' + ); + + subject.set('regexEnabled', false); + + assert.deepEqual( + subject.get('listSearched'), + [], + 'Nothing is matched now that regex is disabled' + ); +}); + +test('each search mode has independent search props', function(assert) { + const subject = this.subject(); + subject.set('source', [ + { id: '1', name: 'United States of America', continent: 'North America' }, + { id: '2', name: 'Canada', continent: 'North America' }, + { id: '3', name: 'Mexico', continent: 'North America' }, + ]); + + subject.set('fuzzySearchEnabled', true); + subject.set('regexSearchProps', ['id']); + subject.set('exactMatchSearchProps', ['continent']); + subject.set('fuzzySearchProps', ['name']); + + subject.set('searchTerm', 'Nor America'); + assert.deepEqual( + subject.get('listSearched'), + [], + 'Not an exact match on continent, not a matchAllTokens match on fuzzy, not a regex match on id' + ); + + subject.set('searchTerm', 'America States'); + assert.deepEqual( + subject.get('listSearched'), + [{ id: '1', name: 'United States of America', continent: 'North America' }], + 'Fuzzy match on one country, but not an exact match on continent' + ); + + subject.set('searchTerm', '^(.a){3}$'); + assert.deepEqual( + subject.get('listSearched'), + [], + 'Canada is not matched by the regex because only id is looked at for regex search' + ); +});