search.e2e.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. describe('Search plugin', function () {
  2. var id = 'testContainer';
  3. beforeEach(function () {
  4. this.$container = $('<div id="' + id + '"></div>').appendTo('body');
  5. });
  6. afterEach(function () {
  7. if (this.$container) {
  8. destroy();
  9. this.$container.remove();
  10. }
  11. });
  12. describe('enabling/disabling plugin', function () {
  13. it('should expose `search` object when plugin is enabled', function () {
  14. var hot = handsontable({
  15. search: true
  16. });
  17. expect(hot.search).toBeDefined();
  18. });
  19. it('should NOT expose `search` object when plugin is disabled', function () {
  20. var hot = handsontable({
  21. search: false
  22. });
  23. expect(hot.search).not.toBeDefined();
  24. });
  25. it('plugin should be disabled by default', function () {
  26. var hot = handsontable();
  27. expect(hot.search).not.toBeDefined();
  28. });
  29. it('should disable plugin using updateSettings', function () {
  30. var hot = handsontable({
  31. search: true
  32. });
  33. expect(hot.search).toBeDefined();
  34. updateSettings({
  35. search: false
  36. });
  37. expect(hot.search).not.toBeDefined();
  38. });
  39. it('should enable plugin using updateSettings', function () {
  40. var hot = handsontable({
  41. search: false
  42. });
  43. expect(hot.search).not.toBeDefined();
  44. updateSettings({
  45. search: true
  46. });
  47. expect(hot.search).toBeDefined();
  48. });
  49. });
  50. describe('query method', function () {
  51. afterEach(function () {
  52. Handsontable.plugins.Search.global.setDefaultQueryMethod(Handsontable.plugins.Search.DEFAULT_QUERY_METHOD);
  53. });
  54. it('should use the default query method if no queryMethod is passed to query function', function () {
  55. spyOn(Handsontable.plugins.Search, 'DEFAULT_QUERY_METHOD');
  56. var defaultQueryMethod = Handsontable.plugins.Search.DEFAULT_QUERY_METHOD;
  57. Handsontable.plugins.Search.global.setDefaultQueryMethod(defaultQueryMethod);
  58. var hot = handsontable({
  59. data: Handsontable.helper.createSpreadsheetData(5, 5),
  60. search: true
  61. });
  62. var searchResult = hot.search.query('A');
  63. expect(defaultQueryMethod.calls.count()).toEqual(25);
  64. });
  65. it('should use the custom default query method if no queryMethod is passed to query function', function () {
  66. var customDefaultQueryMethod = jasmine.createSpy('customDefaultQueryMethod');
  67. var hot = handsontable({
  68. data: Handsontable.helper.createSpreadsheetData(5, 5),
  69. search: true
  70. });
  71. Handsontable.plugins.Search.global.setDefaultQueryMethod(customDefaultQueryMethod);
  72. var searchResult = hot.search.query('A');
  73. expect(customDefaultQueryMethod.calls.count()).toEqual(25);
  74. });
  75. it('should use the query method from the constructor if no queryMethod is passed to query function', function () {
  76. var customQueryMethod = jasmine.createSpy('customDefaultQueryMethod');
  77. var hot = handsontable({
  78. data: Handsontable.helper.createSpreadsheetData(5, 5),
  79. search: {
  80. queryMethod: customQueryMethod
  81. }
  82. });
  83. var searchResult = hot.search.query('A');
  84. expect(customQueryMethod.calls.count()).toEqual(25);
  85. });
  86. it('should use method passed to query function', function () {
  87. var customQueryMethod = jasmine.createSpy('customQueryMethod');
  88. var hot = handsontable({
  89. data: Handsontable.helper.createSpreadsheetData(5, 5),
  90. search: true
  91. });
  92. var searchResult = hot.search.query('A', null, customQueryMethod);
  93. expect(customQueryMethod.calls.count()).toEqual(25);
  94. });
  95. });
  96. describe('default query method', function () {
  97. it('should use query method to find phrase', function () {
  98. var hot = handsontable({
  99. data: Handsontable.helper.createSpreadsheetData(5, 5),
  100. search: true
  101. });
  102. var searchResult = hot.search.query('A');
  103. expect(searchResult.length).toEqual(5);
  104. for (var i = 0; i < searchResult.length; i++) {
  105. expect(searchResult[i].row).toEqual(i);
  106. expect(searchResult[i].col).toEqual(0);
  107. expect(searchResult[i].data).toEqual(hot.getDataAtCell(i, 0));
  108. }
  109. });
  110. it('default query method should be case insensitive', function () {
  111. var hot = handsontable({
  112. data: Handsontable.helper.createSpreadsheetData(5, 5),
  113. search: true
  114. });
  115. var searchResult = hot.search.query('a');
  116. expect(searchResult.length).toEqual(5);
  117. searchResult = hot.search.query('A');
  118. expect(searchResult.length).toEqual(5);
  119. });
  120. it('default query method should work with numeric values', function () {
  121. var hot = handsontable({
  122. data: [[1, 2], [22, 4]],
  123. search: true
  124. });
  125. var searchResult = hot.search.query('2');
  126. expect(searchResult.length).toEqual(2);
  127. });
  128. it('default query method should interpret query as string, not regex', function () {
  129. var hot = handsontable({
  130. data: Handsontable.helper.createSpreadsheetData(5, 5),
  131. search: true
  132. });
  133. var searchResult = hot.search.query('A*');
  134. expect(searchResult.length).toEqual(0);
  135. });
  136. it('default query method should always return false if query string is empty', function () {
  137. var hot = handsontable({
  138. data: Handsontable.helper.createSpreadsheetData(5, 5),
  139. search: true
  140. });
  141. var searchResult = hot.search.query('A');
  142. expect(searchResult.length).toEqual(5);
  143. searchResult = hot.search.query('');
  144. expect(searchResult.length).toEqual(0);
  145. });
  146. it('default query method should always return false if no query string has been specified', function () {
  147. var hot = handsontable({
  148. data: Handsontable.helper.createSpreadsheetData(5, 5),
  149. search: true
  150. });
  151. var searchResult = hot.search.query('A');
  152. expect(searchResult.length).toEqual(5);
  153. searchResult = hot.search.query();
  154. expect(searchResult.length).toEqual(0);
  155. });
  156. it('default query method should always return false if no query string is not a string', function () {
  157. var hot = handsontable({
  158. data: Handsontable.helper.createSpreadsheetData(5, 5),
  159. search: true
  160. });
  161. var searchResult = hot.search.query('A');
  162. expect(searchResult.length).toEqual(5);
  163. searchResult = hot.search.query([1, 2, 3]);
  164. expect(searchResult.length).toEqual(0);
  165. });
  166. });
  167. describe('search callback', function () {
  168. afterEach(function () {
  169. Handsontable.plugins.Search.global.setDefaultCallback(Handsontable.plugins.Search.DEFAULT_CALLBACK);
  170. });
  171. it('should invoke default callback for each cell', function () {
  172. spyOn(Handsontable.plugins.Search, 'DEFAULT_CALLBACK');
  173. var defaultCallback = Handsontable.plugins.Search.DEFAULT_CALLBACK;
  174. Handsontable.plugins.Search.global.setDefaultCallback(defaultCallback);
  175. var hot = handsontable({
  176. data: Handsontable.helper.createSpreadsheetData(5, 5),
  177. search: true
  178. });
  179. var searchResult = hot.search.query('A');
  180. expect(defaultCallback.calls.count()).toEqual(25);
  181. });
  182. it('should change the default callback', function () {
  183. spyOn(Handsontable.plugins.Search, 'DEFAULT_CALLBACK');
  184. var hot = handsontable({
  185. data: Handsontable.helper.createSpreadsheetData(5, 5),
  186. search: true
  187. });
  188. var defaultCallback = jasmine.createSpy('defaultCallback');
  189. Handsontable.plugins.Search.global.setDefaultCallback(defaultCallback);
  190. var searchResult = hot.search.query('A');
  191. expect(Handsontable.plugins.Search.DEFAULT_CALLBACK).not.toHaveBeenCalled();
  192. expect(defaultCallback.calls.count()).toEqual(25);
  193. });
  194. it('should invoke callback passed in constructor', function () {
  195. var searchCallback = jasmine.createSpy('searchCallback');
  196. var hot = handsontable({
  197. data: Handsontable.helper.createSpreadsheetData(5, 5),
  198. search: {
  199. callback: searchCallback
  200. }
  201. });
  202. var searchResult = hot.search.query('A');
  203. expect(searchCallback.calls.count()).toEqual(25);
  204. });
  205. it('should invoke custom callback for each cell which has been tested', function () {
  206. var hot = handsontable({
  207. data: Handsontable.helper.createSpreadsheetData(5, 5),
  208. search: true
  209. });
  210. var searchCallback = jasmine.createSpy('searchCallback');
  211. var searchResult = hot.search.query('A', searchCallback);
  212. expect(searchCallback.calls.count()).toEqual(25);
  213. for (var rowIndex = 0, rowCount = countRows(); rowIndex < rowCount; rowIndex++) {
  214. for (var colIndex = 0, colCount = countCols(); colIndex < colCount; colIndex++) {
  215. var callArgs = searchCallback.calls.argsFor(rowIndex * 5 + colIndex);
  216. expect(callArgs[0]).toEqual(hot);
  217. expect(callArgs[1]).toEqual(rowIndex);
  218. expect(callArgs[2]).toEqual(colIndex);
  219. expect(callArgs[3]).toEqual(hot.getDataAtCell(rowIndex, colIndex));
  220. if (colIndex == 0) {
  221. expect(callArgs[4]).toBe(true);
  222. } else {
  223. expect(callArgs[4]).toBe(false);
  224. }
  225. }
  226. }
  227. });
  228. });
  229. describe('default search callback', function () {
  230. it('should add isSearchResult = true, to cell properties of all matched cells', function () {
  231. var hot = handsontable({
  232. data: Handsontable.helper.createSpreadsheetData(5, 5),
  233. search: true
  234. });
  235. var searchResult = hot.search.query('2');
  236. for (var rowIndex = 0, rowCount = countRows(); rowIndex < rowCount; rowIndex++) {
  237. for (var colIndex = 0, colCount = countCols(); colIndex < colCount; colIndex++) {
  238. var cellProperties = getCellMeta(rowIndex, colIndex);
  239. if (rowIndex == 1) {
  240. expect(cellProperties.isSearchResult).toBeTruthy();
  241. } else {
  242. expect(cellProperties.isSearchResult).toBeFalsy();
  243. }
  244. }
  245. }
  246. });
  247. });
  248. describe('search result decorator', function () {
  249. it('should add default search result class to cells which mach the query', function () {
  250. var hot = handsontable({
  251. data: Handsontable.helper.createSpreadsheetData(5, 5),
  252. search: true
  253. });
  254. var searchResult = hot.search.query('2');
  255. render();
  256. for (var rowIndex = 0, rowCount = countRows(); rowIndex < rowCount; rowIndex++) {
  257. for (var colIndex = 0, colCount = countCols(); colIndex < colCount; colIndex++) {
  258. var cell = getCell(rowIndex, colIndex);
  259. if (rowIndex == 1) {
  260. expect($(cell).hasClass(Handsontable.plugins.Search.DEFAULT_SEARCH_RESULT_CLASS)).toBe(true);
  261. } else {
  262. expect($(cell).hasClass(Handsontable.plugins.Search.DEFAULT_SEARCH_RESULT_CLASS)).toBe(false);
  263. }
  264. }
  265. }
  266. });
  267. it('should add custom search result class to cells which mach the query', function () {
  268. var hot = handsontable({
  269. data: Handsontable.helper.createSpreadsheetData(5, 5),
  270. search: {
  271. searchResultClass: 'customSearchResultClass'
  272. }
  273. });
  274. var searchResult = hot.search.query('2');
  275. render();
  276. for (var rowIndex = 0, rowCount = countRows(); rowIndex < rowCount; rowIndex++) {
  277. for (var colIndex = 0, colCount = countCols(); colIndex < colCount; colIndex++) {
  278. var cell = getCell(rowIndex, colIndex);
  279. if (rowIndex == 1) {
  280. expect($(cell).hasClass('customSearchResultClass')).toBe(true);
  281. } else {
  282. expect($(cell).hasClass('customSearchResultClass')).toBe(false);
  283. }
  284. }
  285. }
  286. });
  287. });
  288. describe('HOT properties compatibility', function () {
  289. it('should work properly when the last row is empty', function () {
  290. // connected with https://github.com/handsontable/handsontable/issues/1606
  291. var hot = handsontable({
  292. data: Handsontable.helper.createSpreadsheetData(5, 5),
  293. colHeaders: true,
  294. search: true,
  295. minSpareRows: 1
  296. }),
  297. errorThrown = false;
  298. try {
  299. hot.search.query('A');
  300. } catch (err) {
  301. errorThrown = true;
  302. }
  303. expect(errorThrown).toBe(false);
  304. });
  305. });
  306. });