search_test.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Distributed under the BSD license:
  3. *
  4. * Copyright (c) 2010, Ajax.org B.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Ajax.org B.V. nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * ***** END LICENSE BLOCK ***** */
  30. if (typeof process !== "undefined") {
  31. require("amd-loader");
  32. }
  33. define(function(require, exports, module) {
  34. "use strict";
  35. var EditSession = require("./edit_session").EditSession;
  36. var MockRenderer = require("./test/mockrenderer").MockRenderer;
  37. var Editor = require("./editor").Editor;
  38. var Search = require("./search").Search;
  39. var assert = require("./test/assertions");
  40. module.exports = {
  41. "test: configure the search object" : function() {
  42. var search = new Search();
  43. search.set({
  44. needle: "juhu"
  45. });
  46. },
  47. "test: find simple text in document" : function() {
  48. var session = new EditSession(["juhu kinners 123", "456"]);
  49. var search = new Search().set({
  50. needle: "kinners"
  51. });
  52. var range = search.find(session);
  53. assert.position(range.start, 0, 5);
  54. assert.position(range.end, 0, 12);
  55. },
  56. "test: find simple text in next line" : function() {
  57. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  58. var search = new Search().set({
  59. needle: "kinners"
  60. });
  61. var range = search.find(session);
  62. assert.position(range.start, 1, 5);
  63. assert.position(range.end, 1, 12);
  64. },
  65. "test: find text starting at cursor position" : function() {
  66. var session = new EditSession(["juhu kinners", "juhu kinners 123"]);
  67. session.getSelection().moveCursorTo(0, 6);
  68. var search = new Search().set({
  69. needle: "kinners"
  70. });
  71. var range = search.find(session);
  72. assert.position(range.start, 1, 5);
  73. assert.position(range.end, 1, 12);
  74. },
  75. "test: wrap search is on by default" : function() {
  76. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  77. session.getSelection().moveCursorTo(2, 1);
  78. var search = new Search().set({
  79. needle: "kinners"
  80. });
  81. assert.notEqual(search.find(session), null);
  82. },
  83. "test: wrap search should wrap at file end" : function() {
  84. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  85. session.getSelection().moveCursorTo(2, 1);
  86. var search = new Search().set({
  87. needle: "kinners",
  88. wrap: true
  89. });
  90. var range = search.find(session);
  91. assert.position(range.start, 1, 5);
  92. assert.position(range.end, 1, 12);
  93. },
  94. "test: wrap search should find needle even if it starts inside it" : function() {
  95. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  96. session.getSelection().moveCursorTo(6, 1);
  97. var search = new Search().set({
  98. needle: "kinners",
  99. wrap: true
  100. });
  101. var range = search.find(session);
  102. assert.position(range.start, 1, 5);
  103. assert.position(range.end, 1, 12);
  104. },
  105. "test: wrap search with no match should return 'null'": function() {
  106. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  107. session.getSelection().moveCursorTo(2, 1);
  108. var search = new Search().set({
  109. needle: "xyz",
  110. wrap: true
  111. });
  112. assert.equal(search.find(session), null);
  113. },
  114. "test: case sensitive is by default off": function() {
  115. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  116. var search = new Search().set({
  117. needle: "JUHU"
  118. });
  119. assert.range(search.find(session), 1, 0, 1, 4);
  120. },
  121. "test: case sensitive search": function() {
  122. var session = new EditSession(["abc", "juhu kinners 123", "456"]);
  123. var search = new Search().set({
  124. needle: "KINNERS",
  125. caseSensitive: true
  126. });
  127. var range = search.find(session);
  128. assert.equal(range, null);
  129. },
  130. "test: whole word search should not match inside of words": function() {
  131. var session = new EditSession(["juhukinners", "juhu kinners 123", "456"]);
  132. var search = new Search().set({
  133. needle: "kinners",
  134. wholeWord: true
  135. });
  136. var range = search.find(session);
  137. assert.position(range.start, 1, 5);
  138. assert.position(range.end, 1, 12);
  139. },
  140. "test: find backwards": function() {
  141. var session = new EditSession(["juhu juhu juhu juhu"]);
  142. session.getSelection().moveCursorTo(0, 10);
  143. var search = new Search().set({
  144. needle: "juhu",
  145. backwards: true
  146. });
  147. var range = search.find(session);
  148. assert.position(range.start, 0, 5);
  149. assert.position(range.end, 0, 9);
  150. },
  151. "test: find in selection": function() {
  152. var session = new EditSession(["juhu", "juhu", "juhu", "juhu"]);
  153. session.getSelection().setSelectionAnchor(1, 0);
  154. session.getSelection().selectTo(3, 5);
  155. var search = new Search().set({
  156. needle: "juhu",
  157. wrap: true,
  158. range: session.getSelection().getRange()
  159. });
  160. var range = search.find(session);
  161. assert.position(range.start, 1, 0);
  162. assert.position(range.end, 1, 4);
  163. search = new Search().set({
  164. needle: "juhu",
  165. wrap: true,
  166. range: session.getSelection().getRange()
  167. });
  168. session.getSelection().setSelectionAnchor(0, 2);
  169. session.getSelection().selectTo(3, 2);
  170. var range = search.find(session);
  171. assert.position(range.start, 1, 0);
  172. assert.position(range.end, 1, 4);
  173. },
  174. "test: find backwards in selection": function() {
  175. var session = new EditSession(["juhu", "juhu", "juhu", "juhu"]);
  176. session.getSelection().setSelectionAnchor(0, 2);
  177. session.getSelection().selectTo(3, 2);
  178. var search = new Search().set({
  179. needle: "juhu",
  180. wrap: true,
  181. backwards: true,
  182. range: session.getSelection().getRange()
  183. });
  184. var range = search.find(session);
  185. assert.position(range.start, 2, 0);
  186. assert.position(range.end, 2, 4);
  187. search = new Search().set({
  188. needle: "juhu",
  189. wrap: true,
  190. range: session.getSelection().getRange()
  191. });
  192. session.getSelection().setSelectionAnchor(0, 2);
  193. session.getSelection().selectTo(1, 2);
  194. var range = search.find(session);
  195. assert.position(range.start, 1, 0);
  196. assert.position(range.end, 1, 4);
  197. },
  198. "test: edge case - match directly before the cursor" : function() {
  199. var session = new EditSession(["123", "123", "juhu"]);
  200. var search = new Search().set({
  201. needle: "juhu",
  202. wrap: true
  203. });
  204. session.getSelection().moveCursorTo(2, 5);
  205. var range = search.find(session);
  206. assert.position(range.start, 2, 0);
  207. assert.position(range.end, 2, 4);
  208. },
  209. "test: edge case - match backwards directly after the cursor" : function() {
  210. var session = new EditSession(["123", "123", "juhu"]);
  211. var search = new Search().set({
  212. needle: "juhu",
  213. wrap: true,
  214. backwards: true
  215. });
  216. session.getSelection().moveCursorTo(2, 0);
  217. var range = search.find(session);
  218. assert.position(range.start, 2, 0);
  219. assert.position(range.end, 2, 4);
  220. },
  221. "test: find using a regular expression" : function() {
  222. var session = new EditSession(["abc123 123 cd", "abc"]);
  223. var search = new Search().set({
  224. needle: "\\d+",
  225. regExp: true
  226. });
  227. var range = search.find(session);
  228. assert.position(range.start, 0, 3);
  229. assert.position(range.end, 0, 6);
  230. },
  231. "test: find using a regular expression and whole word" : function() {
  232. var session = new EditSession(["abc123 123 cd", "abc"]);
  233. var search = new Search().set({
  234. needle: "\\d+\\b",
  235. regExp: true,
  236. wholeWord: true
  237. });
  238. var range = search.find(session);
  239. assert.position(range.start, 0, 7);
  240. assert.position(range.end, 0, 10);
  241. },
  242. "test: use regular expressions with capture groups": function() {
  243. var session = new EditSession([" ab: 12px", " <h1 abc"]);
  244. var search = new Search().set({
  245. needle: "(\\d+)",
  246. regExp: true
  247. });
  248. var range = search.find(session);
  249. assert.position(range.start, 0, 6);
  250. assert.position(range.end, 0, 8);
  251. },
  252. "test: find all matches in selection" : function() {
  253. var session = new EditSession(["juhu", "juhu", "juhu", "juhu"]);
  254. session.getSelection().setSelectionAnchor(0, 2);
  255. session.getSelection().selectTo(3, 2);
  256. var search = new Search().set({
  257. needle: "uh",
  258. wrap: true,
  259. range: session.getSelection().getRange()
  260. });
  261. var ranges = search.findAll(session);
  262. assert.equal(ranges.length, 2);
  263. assert.position(ranges[0].start, 1, 1);
  264. assert.position(ranges[0].end, 1, 3);
  265. assert.position(ranges[1].start, 2, 1);
  266. assert.position(ranges[1].end, 2, 3);
  267. },
  268. "test: find all multiline matches" : function() {
  269. var session = new EditSession(["juhu", "juhu", "juhu", "juhu"]);
  270. var search = new Search().set({
  271. needle: "hu\nju",
  272. wrap: true
  273. });
  274. var ranges = search.findAll(session);
  275. assert.equal(ranges.length, 3);
  276. assert.position(ranges[0].start, 0, 2);
  277. assert.position(ranges[0].end, 1, 2);
  278. assert.position(ranges[1].start, 1, 2);
  279. assert.position(ranges[1].end, 2, 2);
  280. },
  281. "test: replace() should return the replacement if the input matches the needle" : function() {
  282. var search = new Search().set({
  283. needle: "juhu"
  284. });
  285. assert.equal(search.replace("juhu", "kinners"), "kinners");
  286. assert.equal(search.replace("", "kinners"), null);
  287. assert.equal(search.replace(" juhu", "kinners"), null);
  288. // case sensitivity
  289. assert.equal(search.replace("Juhu", "kinners"), "kinners");
  290. search.set({caseSensitive: true});
  291. assert.equal(search.replace("Juhu", "kinners"), null);
  292. // regexp replacement
  293. },
  294. "test: replace with a RegExp search" : function() {
  295. var search = new Search().set({
  296. needle: "\\d+",
  297. regExp: true
  298. });
  299. assert.equal(search.replace("123", "kinners"), "kinners");
  300. assert.equal(search.replace("01234", "kinners"), "kinners");
  301. assert.equal(search.replace("", "kinners"), null);
  302. assert.equal(search.replace("a12", "kinners"), null);
  303. assert.equal(search.replace("12a", "kinners"), null);
  304. },
  305. "test: replace with RegExp match and capture groups" : function() {
  306. var search = new Search().set({
  307. needle: "ab(\\d\\d)",
  308. regExp: true
  309. });
  310. assert.equal(search.replace("ab12", "cd$1"), "cd12");
  311. assert.equal(search.replace("ab12", "-$&-"), "-ab12-");
  312. assert.equal(search.replace("ab12", "$$"), "$");
  313. },
  314. "test: find all using regular expresion containing $" : function() {
  315. var session = new EditSession(["a", " b", "c ", "d"]);
  316. var search = new Search().set({
  317. needle: "[ ]+$",
  318. regExp: true,
  319. wrap: true
  320. });
  321. session.getSelection().moveCursorTo(1, 2);
  322. var ranges = search.findAll(session);
  323. assert.equal(ranges.length, 1);
  324. assert.position(ranges[0].start, 2, 1);
  325. assert.position(ranges[0].end, 2, 2);
  326. },
  327. "test: find all matches in a line" : function() {
  328. var session = new EditSession("foo bar foo baz foobar foo");
  329. var search = new Search().set({
  330. needle: "foo",
  331. wrap: true,
  332. wholeWord: true
  333. });
  334. session.getSelection().moveCursorTo(0, 4);
  335. var ranges = search.findAll(session);
  336. assert.equal(ranges.length, 3);
  337. assert.position(ranges[0].start, 0, 0);
  338. assert.position(ranges[0].end, 0, 3);
  339. assert.position(ranges[1].start, 0, 8);
  340. assert.position(ranges[1].end, 0, 11);
  341. assert.position(ranges[2].start, 0, 23);
  342. assert.position(ranges[2].end, 0, 26);
  343. },
  344. "test: find all matches in a line backwards" : function() {
  345. var session = new EditSession("foo bar foo baz foobar foo");
  346. var search = new Search().set({
  347. needle: "foo",
  348. wrap: true,
  349. wholeWord: true,
  350. backwards: true
  351. });
  352. session.getSelection().moveCursorTo(0, 13);
  353. var ranges = search.findAll(session);
  354. assert.equal(ranges.length, 3);
  355. assert.position(ranges[2].start, 0, 23);
  356. assert.position(ranges[2].end, 0, 26);
  357. assert.position(ranges[1].start, 0, 8);
  358. assert.position(ranges[1].end, 0, 11);
  359. assert.position(ranges[0].start, 0, 0);
  360. assert.position(ranges[0].end, 0, 3);
  361. },
  362. "test: find next empty range" : function() {
  363. var session = new EditSession("foo foobar foo");
  364. var editor = new Editor(new MockRenderer(), session);
  365. var options = {
  366. needle: "o*",
  367. wrap: true,
  368. regExp: true,
  369. backwards: false
  370. };
  371. var positions = [4, 5.2, 7, 8, 9, 10, 11, 12.2, 14, 0, 1.2, 3];
  372. session.selection.moveCursorTo(0, 3);
  373. for (var i = 0; i < 12; i++) {
  374. editor.find(options)
  375. var range = editor.selection.getRange();
  376. var start = range.start.column;
  377. var len = range.end.column - start;
  378. assert.equal(start + 0.1 * len, positions[i])
  379. }
  380. options.backwards = true;
  381. positions = [1.2, 1, 0, 14, 12.2, 12, 11, 10, 9, 8, 7, 5.2, 5, 4, 3];
  382. for (var i = 0; i < 16; i++) {
  383. editor.find(options);
  384. var range = editor.selection.getRange();
  385. var start = range.start.column;
  386. var len = range.end.column - start;
  387. console.log(start + 0.1 * len)
  388. }
  389. }
  390. };
  391. });
  392. if (typeof module !== "undefined" && module === require.main) {
  393. require("asyncjs").test.testcase(module.exports).exec()
  394. }