edit_session_test.js 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  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. require("./test/mockdom");
  33. }
  34. define(function(require, exports, module) {
  35. "use strict";
  36. var lang = require("./lib/lang");
  37. var EditSession = require("./edit_session").EditSession;
  38. var Editor = require("./editor").Editor;
  39. var UndoManager = require("./undomanager").UndoManager;
  40. var MockRenderer = require("./test/mockrenderer").MockRenderer;
  41. var Range = require("./range").Range;
  42. var assert = require("./test/assertions");
  43. var JavaScriptMode = require("./mode/javascript").Mode;
  44. function createFoldTestSession() {
  45. var lines = [
  46. "function foo(items) {",
  47. " for (var i=0; i<items.length; i++) {",
  48. " alert(items[i] + \"juhu\");",
  49. " } // Real Tab.",
  50. "}"
  51. ];
  52. var session = new EditSession(lines.join("\n"));
  53. session.setUndoManager(new UndoManager());
  54. session.addFold("args...", new Range(0, 13, 0, 18));
  55. session.addFold("foo...", new Range(1, 10, 2, 10));
  56. session.addFold("bar...", new Range(2, 20, 2, 25));
  57. return session;
  58. }
  59. function assertArray(a, b) {
  60. assert.equal(a+"", b+"");
  61. assert.ok(a.length == b.length);
  62. for (var i = 0; i < a.length; i++) {
  63. assert.equal(a[i], b[i]);
  64. }
  65. }
  66. module.exports = {
  67. "test: find matching opening bracket in Text mode" : function() {
  68. var session = new EditSession(["(()(", "())))"]);
  69. assert.position(session.findMatchingBracket({row: 0, column: 3}), 0, 1);
  70. assert.position(session.findMatchingBracket({row: 1, column: 2}), 1, 0);
  71. assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 3);
  72. assert.position(session.findMatchingBracket({row: 1, column: 4}), 0, 0);
  73. assert.equal(session.findMatchingBracket({row: 1, column: 5}), null);
  74. },
  75. "test: find matching closing bracket in Text mode" : function() {
  76. var session = new EditSession(["(()(", "())))"]);
  77. assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1);
  78. assert.position(session.findMatchingBracket({row: 1, column: 1}), 1, 1);
  79. assert.position(session.findMatchingBracket({row: 0, column: 4}), 1, 2);
  80. assert.position(session.findMatchingBracket({row: 0, column: 2}), 0, 2);
  81. assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 3);
  82. assert.equal(session.findMatchingBracket({row: 0, column: 0}), null);
  83. },
  84. "test: find matching opening bracket in JavaScript mode" : function() {
  85. var lines = [
  86. "function foo() {",
  87. " var str = \"{ foo()\";",
  88. " if (debug) {",
  89. " // write str (a string) to the console",
  90. " console.log(str);",
  91. " }",
  92. " str += \" bar() }\";",
  93. "}"
  94. ];
  95. var session = new EditSession(lines.join("\n"), new JavaScriptMode());
  96. assert.position(session.findMatchingBracket({row: 0, column: 14}), 0, 12);
  97. assert.position(session.findMatchingBracket({row: 7, column: 1}), 0, 15);
  98. assert.position(session.findMatchingBracket({row: 6, column: 20}), 1, 15);
  99. assert.position(session.findMatchingBracket({row: 1, column: 22}), 1, 20);
  100. assert.position(session.findMatchingBracket({row: 3, column: 31}), 3, 21);
  101. assert.position(session.findMatchingBracket({row: 4, column: 24}), 4, 19);
  102. assert.equal(session.findMatchingBracket({row: 0, column: 1}), null);
  103. },
  104. "test: find matching closing bracket in JavaScript mode" : function() {
  105. var lines = [
  106. "function foo() {",
  107. " var str = \"{ foo()\";",
  108. " if (debug) {",
  109. " // write str (a string) to the console",
  110. " console.log(str);",
  111. " }",
  112. " str += \" bar() }\";",
  113. "}"
  114. ];
  115. var session = new EditSession(lines.join("\n"), new JavaScriptMode());
  116. assert.position(session.findMatchingBracket({row: 0, column: 13}), 0, 13);
  117. assert.position(session.findMatchingBracket({row: 0, column: 16}), 7, 0);
  118. assert.position(session.findMatchingBracket({row: 1, column: 16}), 6, 19);
  119. assert.position(session.findMatchingBracket({row: 1, column: 21}), 1, 21);
  120. assert.position(session.findMatchingBracket({row: 3, column: 22}), 3, 30);
  121. assert.position(session.findMatchingBracket({row: 4, column: 20}), 4, 23);
  122. },
  123. "test: handle unbalanced brackets in JavaScript mode" : function() {
  124. var lines = [
  125. "function foo() {",
  126. " var str = \"{ foo()\";",
  127. " if (debug) {",
  128. " // write str a string) to the console",
  129. " console.log(str);",
  130. " ",
  131. " str += \" bar() \";",
  132. "}"
  133. ];
  134. var session = new EditSession(lines.join("\n"), new JavaScriptMode());
  135. assert.equal(session.findMatchingBracket({row: 0, column: 16}), null);
  136. assert.equal(session.findMatchingBracket({row: 3, column: 30}), null);
  137. assert.equal(session.findMatchingBracket({row: 1, column: 16}), null);
  138. },
  139. "test: match different bracket types" : function() {
  140. var session = new EditSession(["({[", ")]}"]);
  141. assert.position(session.findMatchingBracket({row: 0, column: 1}), 1, 0);
  142. assert.position(session.findMatchingBracket({row: 0, column: 2}), 1, 2);
  143. assert.position(session.findMatchingBracket({row: 0, column: 3}), 1, 1);
  144. assert.position(session.findMatchingBracket({row: 1, column: 1}), 0, 0);
  145. assert.position(session.findMatchingBracket({row: 1, column: 2}), 0, 2);
  146. assert.position(session.findMatchingBracket({row: 1, column: 3}), 0, 1);
  147. },
  148. "test: move lines down" : function() {
  149. var session = new EditSession(["a1", "a2", "a3", "a4"]);
  150. session.moveLinesDown(0, 1);
  151. assert.equal(session.getValue(), ["a3", "a1", "a2", "a4"].join("\n"));
  152. session.moveLinesDown(1, 2);
  153. assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
  154. session.moveLinesDown(2, 3);
  155. assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
  156. session.moveLinesDown(2, 2);
  157. assert.equal(session.getValue(), ["a3", "a4", "a2", "a1"].join("\n"));
  158. },
  159. "test: move lines up" : function() {
  160. var session = new EditSession(["a1", "a2", "a3", "a4"]);
  161. session.moveLinesUp(2, 3);
  162. assert.equal(session.getValue(), ["a1", "a3", "a4", "a2"].join("\n"));
  163. session.moveLinesUp(1, 2);
  164. assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
  165. session.moveLinesUp(0, 1);
  166. assert.equal(session.getValue(), ["a3", "a4", "a1", "a2"].join("\n"));
  167. session.moveLinesUp(2, 2);
  168. assert.equal(session.getValue(), ["a3", "a1", "a4", "a2"].join("\n"));
  169. },
  170. "test: duplicate lines" : function() {
  171. var session = new EditSession(["1", "2", "3", "4"]);
  172. session.duplicateLines(1, 2);
  173. assert.equal(session.getValue(), ["1", "2", "3", "2", "3", "4"].join("\n"));
  174. },
  175. "test: duplicate last line" : function() {
  176. var session = new EditSession(["1", "2", "3"]);
  177. session.duplicateLines(2, 2);
  178. assert.equal(session.getValue(), ["1", "2", "3", "3"].join("\n"));
  179. },
  180. "test: duplicate first line" : function() {
  181. var session = new EditSession(["1", "2", "3"]);
  182. session.duplicateLines(0, 0);
  183. assert.equal(session.getValue(), ["1", "1", "2", "3"].join("\n"));
  184. },
  185. "test: getScreenLastRowColumn": function() {
  186. var session = new EditSession([
  187. "juhu",
  188. "12\t\t34",
  189. "ぁぁa"
  190. ]);
  191. assert.equal(session.getScreenLastRowColumn(0), 4);
  192. assert.equal(session.getScreenLastRowColumn(1), 10);
  193. assert.equal(session.getScreenLastRowColumn(2), 5);
  194. },
  195. "test: convert document to screen coordinates" : function() {
  196. var session = new EditSession("01234\t567890\t1234");
  197. session.setTabSize(4);
  198. assert.equal(session.documentToScreenColumn(0, 0), 0);
  199. assert.equal(session.documentToScreenColumn(0, 4), 4);
  200. assert.equal(session.documentToScreenColumn(0, 5), 5);
  201. assert.equal(session.documentToScreenColumn(0, 6), 8);
  202. assert.equal(session.documentToScreenColumn(0, 12), 14);
  203. assert.equal(session.documentToScreenColumn(0, 13), 16);
  204. session.setTabSize(2);
  205. assert.equal(session.documentToScreenColumn(0, 0), 0);
  206. assert.equal(session.documentToScreenColumn(0, 4), 4);
  207. assert.equal(session.documentToScreenColumn(0, 5), 5);
  208. assert.equal(session.documentToScreenColumn(0, 6), 6);
  209. assert.equal(session.documentToScreenColumn(0, 7), 7);
  210. assert.equal(session.documentToScreenColumn(0, 12), 12);
  211. assert.equal(session.documentToScreenColumn(0, 13), 14);
  212. },
  213. "test: convert document to screen coordinates with leading tabs": function() {
  214. var session = new EditSession("\t\t123");
  215. session.setTabSize(4);
  216. assert.equal(session.documentToScreenColumn(0, 0), 0);
  217. assert.equal(session.documentToScreenColumn(0, 1), 4);
  218. assert.equal(session.documentToScreenColumn(0, 2), 8);
  219. assert.equal(session.documentToScreenColumn(0, 3), 9);
  220. },
  221. "test: documentToScreen without soft wrap": function() {
  222. var session = new EditSession([
  223. "juhu",
  224. "12\t\t34",
  225. "ぁぁa"
  226. ]);
  227. assert.position(session.documentToScreenPosition(0, 3), 0, 3);
  228. assert.position(session.documentToScreenPosition(1, 3), 1, 4);
  229. assert.position(session.documentToScreenPosition(1, 4), 1, 8);
  230. assert.position(session.documentToScreenPosition(2, 2), 2, 4);
  231. },
  232. "test: documentToScreen with soft wrap": function() {
  233. var session = new EditSession(["foo bar foo bar"]);
  234. session.setUseWrapMode(true);
  235. session.setWrapLimitRange(12, 12);
  236. session.adjustWrapLimit(80);
  237. assert.position(session.documentToScreenPosition(0, 11), 0, 11);
  238. assert.position(session.documentToScreenPosition(0, 12), 1, 0);
  239. },
  240. "test: documentToScreen with soft wrap and multibyte characters": function() {
  241. var session = new EditSession(["ぁぁa"]);
  242. session.setUseWrapMode(true);
  243. session.setWrapLimitRange(2, 2);
  244. session.adjustWrapLimit(80);
  245. assert.position(session.documentToScreenPosition(0, 1), 1, 0);
  246. assert.position(session.documentToScreenPosition(0, 2), 2, 0);
  247. assert.position(session.documentToScreenPosition(0, 4), 2, 1);
  248. },
  249. "test: documentToScreen should clip position to the document boundaries": function() {
  250. var session = new EditSession("foo bar\njuhu kinners");
  251. assert.position(session.documentToScreenPosition(-1, 4), 0, 0);
  252. assert.position(session.documentToScreenPosition(3, 0), 1, 12);
  253. },
  254. "test: convert screen to document coordinates" : function() {
  255. var session = new EditSession("01234\t567890\t1234");
  256. session.setTabSize(4);
  257. assert.equal(session.screenToDocumentColumn(0, 0), 0);
  258. assert.equal(session.screenToDocumentColumn(0, 4), 4);
  259. assert.equal(session.screenToDocumentColumn(0, 5), 5);
  260. assert.equal(session.screenToDocumentColumn(0, 6), 5);
  261. assert.equal(session.screenToDocumentColumn(0, 7), 5);
  262. assert.equal(session.screenToDocumentColumn(0, 8), 6);
  263. assert.equal(session.screenToDocumentColumn(0, 9), 7);
  264. assert.equal(session.screenToDocumentColumn(0, 15), 12);
  265. assert.equal(session.screenToDocumentColumn(0, 19), 16);
  266. session.setTabSize(2);
  267. assert.equal(session.screenToDocumentColumn(0, 0), 0);
  268. assert.equal(session.screenToDocumentColumn(0, 4), 4);
  269. assert.equal(session.screenToDocumentColumn(0, 5), 5);
  270. assert.equal(session.screenToDocumentColumn(0, 6), 6);
  271. assert.equal(session.screenToDocumentColumn(0, 12), 12);
  272. assert.equal(session.screenToDocumentColumn(0, 13), 12);
  273. assert.equal(session.screenToDocumentColumn(0, 14), 13);
  274. },
  275. "test: screenToDocument with soft wrap": function() {
  276. var session = new EditSession(["foo bar foo bar"]);
  277. session.setUseWrapMode(true);
  278. session.setWrapLimitRange(12, 12);
  279. session.adjustWrapLimit(80);
  280. assert.position(session.screenToDocumentPosition(1, 0), 0, 12);
  281. assert.position(session.screenToDocumentPosition(0, 11), 0, 11);
  282. // Check if the position is clamped the right way.
  283. assert.position(session.screenToDocumentPosition(0, 12), 0, 11);
  284. assert.position(session.screenToDocumentPosition(0, 20), 0, 11);
  285. },
  286. "test: screenToDocument with soft wrap and multi byte characters": function() {
  287. var session = new EditSession(["ぁ a"]);
  288. session.setUseWrapMode(true);
  289. session.adjustWrapLimit(80);
  290. assert.position(session.screenToDocumentPosition(0, 1), 0, 0);
  291. assert.position(session.screenToDocumentPosition(0, 2), 0, 1);
  292. assert.position(session.screenToDocumentPosition(0, 3), 0, 2);
  293. assert.position(session.screenToDocumentPosition(0, 4), 0, 3);
  294. assert.position(session.screenToDocumentPosition(0, 5), 0, 3);
  295. },
  296. "test: screenToDocument should clip position to the document boundaries": function() {
  297. var session = new EditSession("foo bar\njuhu kinners");
  298. assert.position(session.screenToDocumentPosition(-1, 4), 0, 0);
  299. assert.position(session.screenToDocumentPosition(0, -1), 0, 0);
  300. assert.position(session.screenToDocumentPosition(0, 30), 0, 7);
  301. assert.position(session.screenToDocumentPosition(2, 4), 1, 12);
  302. assert.position(session.screenToDocumentPosition(1, 30), 1, 12);
  303. assert.position(session.screenToDocumentPosition(20, 50), 1, 12);
  304. assert.position(session.screenToDocumentPosition(20, 5), 1, 12);
  305. // and the same for folded rows
  306. session.addFold("...", new Range(0,1,1,3));
  307. assert.position(session.screenToDocumentPosition(1, 2), 1, 12);
  308. // for wrapped rows
  309. session.setUseWrapMode(true);
  310. session.setWrapLimitRange(5,5);
  311. assert.position(session.screenToDocumentPosition(4, 1), 1, 12);
  312. },
  313. "test: wrapLine split function" : function() {
  314. function computeAndAssert(line, assertEqual, wrapLimit, tabSize) {
  315. wrapLimit = wrapLimit || 12;
  316. tabSize = tabSize || 4;
  317. line = lang.stringTrimRight(line);
  318. var tokens = EditSession.prototype.$getDisplayTokens(line);
  319. var splits = EditSession.prototype.$computeWrapSplits(tokens, wrapLimit, tabSize);
  320. // console.log("String:", line, "Result:", splits, "Expected:", assertEqual);
  321. assert.ok(splits.length == assertEqual.length);
  322. for (var i = 0; i < splits.length; i++) {
  323. assert.ok(splits[i] == assertEqual[i]);
  324. }
  325. }
  326. EditSession.prototype.$wrapAsCode = true;
  327. // Basic splitting.
  328. computeAndAssert("foo bar foo bar", [ 12 ]);
  329. computeAndAssert("foo bar f bar", [ 12 ]);
  330. computeAndAssert("foo bar f r", [ 12 ]); // 14 if we enable
  331. computeAndAssert("foo bar foo bar foo bara foo", [12, 25]);
  332. // Don't split if there is only whitespaces/tabs at the end of the line.
  333. computeAndAssert("foo foo foo \t \t", [ ]);
  334. // If there is no space to split, force split.
  335. computeAndAssert("foooooooooooooo", [ 12 ]);
  336. computeAndAssert("fooooooooooooooooooooooooooo", [12, 24]);
  337. computeAndAssert("foo bar fooooooooooobooooooo", [8, 20]);
  338. // Basic splitting + tabs.
  339. computeAndAssert("foo \t\tbar", [ 6 ]);
  340. computeAndAssert("foo \t \tbar", [ 7 ]);
  341. // Ignore spaces/tabs at beginning of split.
  342. computeAndAssert("foo \t \t \t \t bar", [ 7 ]); // 14
  343. // Test wrapping for asian characters.
  344. computeAndAssert("ぁぁ", [1], 2);
  345. computeAndAssert(" ぁぁ", [1, 2], 2);
  346. computeAndAssert(" ぁ\tぁ", [1, 3], 2);
  347. computeAndAssert(" ぁぁ\tぁ", [1, 4], 4);
  348. // Test wrapping for punctuation.
  349. computeAndAssert(" ab.c;ef++", [1, 3, 5, 7, 8], 2);
  350. computeAndAssert(" a.b", [1, 2, 3], 1);
  351. computeAndAssert("#>>", [1, 2], 1);
  352. // Test wrapping for punctuation in
  353. EditSession.prototype.$wrapAsCode = false;
  354. computeAndAssert("ab cde, Juhu kinners", [3, 8, 13, 19], 6);
  355. },
  356. "test get longest line" : function() {
  357. var session = new EditSession(["12"]);
  358. session.setTabSize(4);
  359. assert.equal(session.getScreenWidth(), 2);
  360. session.doc.insertNewLine({row: 0, column: Infinity});
  361. session.doc.insertLines(1, ["123"]);
  362. assert.equal(session.getScreenWidth(), 3);
  363. session.doc.insertNewLine({row: 0, column: Infinity});
  364. session.doc.insertLines(1, ["\t\t"]);
  365. assert.equal(session.getScreenWidth(), 8);
  366. session.setTabSize(2);
  367. assert.equal(session.getScreenWidth(), 4);
  368. },
  369. "test getDisplayString": function() {
  370. var session = new EditSession(["12"]);
  371. session.setTabSize(4);
  372. assert.equal(session.$getDisplayTokens("\t").length, 4);
  373. assert.equal(session.$getDisplayTokens("abc").length, 3);
  374. assert.equal(session.$getDisplayTokens("abc\t").length, 4);
  375. },
  376. "test issue 83": function() {
  377. var session = new EditSession("");
  378. var editor = new Editor(new MockRenderer(), session);
  379. var document = session.getDocument();
  380. session.setUseWrapMode(true);
  381. document.insertLines(0, ["a", "b"]);
  382. document.insertLines(2, ["c", "d"]);
  383. document.removeLines(1, 2);
  384. },
  385. "test wrapMode init has to create wrapData array": function() {
  386. var session = new EditSession("foo bar\nfoo bar");
  387. var editor = new Editor(new MockRenderer(), session);
  388. var document = session.getDocument();
  389. session.setUseWrapMode(true);
  390. session.setWrapLimitRange(3, 3);
  391. session.adjustWrapLimit(80);
  392. // Test if wrapData is there and was computed.
  393. assert.equal(session.$wrapData.length, 2);
  394. assert.equal(session.$wrapData[0].length, 1);
  395. assert.equal(session.$wrapData[1].length, 1);
  396. },
  397. "test first line blank with wrap": function() {
  398. var session = new EditSession("\nfoo");
  399. session.setUseWrapMode(true);
  400. assert.equal(session.doc.getValue(), ["", "foo"].join("\n"));
  401. },
  402. "test first line blank with wrap 2" : function() {
  403. var session = new EditSession("");
  404. session.setUseWrapMode(true);
  405. session.setValue("\nfoo");
  406. assert.equal(session.doc.getValue(), ["", "foo"].join("\n"));
  407. },
  408. "test fold getFoldDisplayLine": function() {
  409. var session = createFoldTestSession();
  410. function assertDisplayLine(foldLine, str) {
  411. var line = session.getLine(foldLine.end.row);
  412. var displayLine =
  413. session.getFoldDisplayLine(foldLine, foldLine.end.row, line.length);
  414. assert.equal(displayLine, str);
  415. }
  416. assertDisplayLine(session.$foldData[0], "function foo(args...) {")
  417. assertDisplayLine(session.$foldData[1], " for (vfoo...ert(items[bar...\"juhu\");");
  418. },
  419. "test foldLine idxToPosition": function() {
  420. var session = createFoldTestSession();
  421. function assertIdx2Pos(foldLineIdx, idx, row, column) {
  422. var foldLine = session.$foldData[foldLineIdx];
  423. assert.position(foldLine.idxToPosition(idx), row, column);
  424. }
  425. // "function foo(items) {",
  426. // " for (var i=0; i<items.length; i++) {",
  427. // " alert(items[i] + \"juhu\");",
  428. // " } // Real Tab.",
  429. // "}"
  430. assertIdx2Pos(0, 12, 0, 12);
  431. assertIdx2Pos(0, 13, 0, 13);
  432. assertIdx2Pos(0, 14, 0, 13);
  433. assertIdx2Pos(0, 19, 0, 13);
  434. assertIdx2Pos(0, 20, 0, 18);
  435. assertIdx2Pos(1, 10, 1, 10);
  436. assertIdx2Pos(1, 11, 1, 10);
  437. assertIdx2Pos(1, 15, 1, 10);
  438. assertIdx2Pos(1, 16, 2, 10);
  439. assertIdx2Pos(1, 26, 2, 20);
  440. assertIdx2Pos(1, 27, 2, 20);
  441. assertIdx2Pos(1, 32, 2, 25);
  442. },
  443. "test fold documentToScreen": function() {
  444. var session = createFoldTestSession();
  445. function assertDoc2Screen(docRow, docCol, screenRow, screenCol) {
  446. assert.position(
  447. session.documentToScreenPosition(docRow, docCol),
  448. screenRow, screenCol
  449. );
  450. }
  451. // One fold ending in the same row.
  452. assertDoc2Screen(0, 0, 0, 0);
  453. assertDoc2Screen(0, 13, 0, 13);
  454. assertDoc2Screen(0, 14, 0, 13);
  455. assertDoc2Screen(0, 17, 0, 13);
  456. assertDoc2Screen(0, 18, 0, 20);
  457. // Fold ending on some other row.
  458. assertDoc2Screen(1, 0, 1, 0);
  459. assertDoc2Screen(1, 10, 1, 10);
  460. assertDoc2Screen(1, 11, 1, 10);
  461. assertDoc2Screen(1, 99, 1, 10);
  462. assertDoc2Screen(2, 0, 1, 10);
  463. assertDoc2Screen(2, 9, 1, 10);
  464. assertDoc2Screen(2, 10, 1, 16);
  465. assertDoc2Screen(2, 11, 1, 17);
  466. // Fold in the same row with fold over more then one row in the same row.
  467. assertDoc2Screen(2, 19, 1, 25);
  468. assertDoc2Screen(2, 20, 1, 26);
  469. assertDoc2Screen(2, 21, 1, 26);
  470. assertDoc2Screen(2, 24, 1, 26);
  471. assertDoc2Screen(2, 25, 1, 32);
  472. assertDoc2Screen(2, 26, 1, 33);
  473. assertDoc2Screen(2, 99, 1, 40);
  474. // Test one position after the folds. Should be all like normal.
  475. assertDoc2Screen(3, 0, 2, 0);
  476. },
  477. "test fold screenToDocument": function() {
  478. var session = createFoldTestSession();
  479. function assertScreen2Doc(docRow, docCol, screenRow, screenCol) {
  480. assert.position(
  481. session.screenToDocumentPosition(screenRow, screenCol),
  482. docRow, docCol
  483. );
  484. }
  485. // One fold ending in the same row.
  486. assertScreen2Doc(0, 0, 0, 0);
  487. assertScreen2Doc(0, 13, 0, 13);
  488. assertScreen2Doc(0, 13, 0, 14);
  489. assertScreen2Doc(0, 18, 0, 20);
  490. assertScreen2Doc(0, 19, 0, 21);
  491. // Fold ending on some other row.
  492. assertScreen2Doc(1, 0, 1, 0);
  493. assertScreen2Doc(1, 10, 1, 10);
  494. assertScreen2Doc(1, 10, 1, 11);
  495. assertScreen2Doc(1, 10, 1, 15);
  496. assertScreen2Doc(2, 10, 1, 16);
  497. assertScreen2Doc(2, 11, 1, 17);
  498. // Fold in the same row with fold over more then one row in the same row.
  499. assertScreen2Doc(2, 19, 1, 25);
  500. assertScreen2Doc(2, 20, 1, 26);
  501. assertScreen2Doc(2, 20, 1, 27);
  502. assertScreen2Doc(2, 20, 1, 31);
  503. assertScreen2Doc(2, 25, 1, 32);
  504. assertScreen2Doc(2, 26, 1, 33);
  505. assertScreen2Doc(2, 33, 1, 99);
  506. // Test one position after the folds. Should be all like normal.
  507. assertScreen2Doc(3, 0, 2, 0);
  508. },
  509. "test getFoldsInRange()": function() {
  510. var session = createFoldTestSession();
  511. var foldLines = session.$foldData;
  512. var folds = foldLines[0].folds.concat(foldLines[1].folds);
  513. function test(startRow, startColumn, endColumn, endRow, folds) {
  514. var r = new Range(startRow, startColumn, endColumn, endRow);
  515. var retFolds = session.getFoldsInRange(r);
  516. assert.ok(retFolds.length == folds.length);
  517. for (var i = 0; i < retFolds.length; i++) {
  518. assert.equal(retFolds[i].range + "", folds[i].range + "");
  519. }
  520. }
  521. test(0, 0, 0, 13, [ ]);
  522. test(0, 0, 0, 14, [ folds[0] ]);
  523. test(0, 0, 0, 18, [ folds[0] ]);
  524. test(0, 0, 1, 10, [ folds[0] ]);
  525. test(0, 0, 1, 11, [ folds[0], folds[1] ]);
  526. test(0, 18, 1, 11, [ folds[1] ]);
  527. test(2, 0, 2, 13, [ folds[1] ]);
  528. test(2, 10, 2, 20, [ ]);
  529. test(2, 10, 2, 11, [ ]);
  530. test(2, 19, 2, 20, [ ]);
  531. },
  532. "test fold one-line text insert": function() {
  533. // These are mostly test for the FoldLine.addRemoveChars function.
  534. var session = createFoldTestSession();
  535. var undoManager = session.getUndoManager();
  536. var foldLines = session.$foldData;
  537. function insert(row, column, text) {
  538. session.insert({row: row, column: column}, text);
  539. // Force the session to store all changes made to the document NOW
  540. // on the undoManager's queue. Otherwise we can't undo in separate
  541. // steps later.
  542. session.$syncInformUndoManager();
  543. }
  544. var foldLine, fold, folds;
  545. // First line.
  546. foldLine = session.$foldData[0];
  547. fold = foldLine.folds[0];
  548. insert(0, 0, "0");
  549. assert.range(foldLine.range, 0, 14, 0, 19);
  550. assert.range(fold.range, 0, 14, 0, 19);
  551. insert(0, 14, "1");
  552. assert.range(foldLine.range, 0, 15, 0, 20);
  553. assert.range(fold.range, 0, 15, 0, 20);
  554. insert(0, 20, "2");
  555. assert.range(foldLine.range, 0, 15, 0, 20);
  556. assert.range(fold.range, 0, 15, 0, 20);
  557. // Second line.
  558. foldLine = session.$foldData[1];
  559. folds = foldLine.folds;
  560. insert(1, 0, "3");
  561. assert.range(foldLine.range, 1, 11, 2, 25);
  562. assert.range(folds[0].range, 1, 11, 2, 10);
  563. assert.range(folds[1].range, 2, 20, 2, 25);
  564. insert(1, 11, "4");
  565. assert.range(foldLine.range, 1, 12, 2, 25);
  566. assert.range(folds[0].range, 1, 12, 2, 10);
  567. assert.range(folds[1].range, 2, 20, 2, 25);
  568. insert(2, 10, "5");
  569. assert.range(foldLine.range, 1, 12, 2, 26);
  570. assert.range(folds[0].range, 1, 12, 2, 10);
  571. assert.range(folds[1].range, 2, 21, 2, 26);
  572. insert(2, 21, "6");
  573. assert.range(foldLine.range, 1, 12, 2, 27);
  574. assert.range(folds[0].range, 1, 12, 2, 10);
  575. assert.range(folds[1].range, 2, 22, 2, 27);
  576. insert(2, 27, "7");
  577. assert.range(foldLine.range, 1, 12, 2, 27);
  578. assert.range(folds[0].range, 1, 12, 2, 10);
  579. assert.range(folds[1].range, 2, 22, 2, 27);
  580. // UNDO = REMOVE
  581. undoManager.undo(); // 6
  582. assert.range(foldLine.range, 1, 12, 2, 27);
  583. assert.range(folds[0].range, 1, 12, 2, 10);
  584. assert.range(folds[1].range, 2, 22, 2, 27);
  585. undoManager.undo(); // 5
  586. assert.range(foldLine.range, 1, 12, 2, 26);
  587. assert.range(folds[0].range, 1, 12, 2, 10);
  588. assert.range(folds[1].range, 2, 21, 2, 26);
  589. undoManager.undo(); // 4
  590. assert.range(foldLine.range, 1, 12, 2, 25);
  591. assert.range(folds[0].range, 1, 12, 2, 10);
  592. assert.range(folds[1].range, 2, 20, 2, 25);
  593. undoManager.undo(); // 3
  594. assert.range(foldLine.range, 1, 11, 2, 25);
  595. assert.range(folds[0].range, 1, 11, 2, 10);
  596. assert.range(folds[1].range, 2, 20, 2, 25);
  597. undoManager.undo(); // Beginning first line.
  598. assert.equal(foldLines.length, 2);
  599. assert.range(foldLines[0].range, 0, 15, 0, 20);
  600. assert.range(foldLines[1].range, 1, 10, 2, 25);
  601. foldLine = session.$foldData[0];
  602. fold = foldLine.folds[0];
  603. undoManager.undo(); // 2
  604. assert.range(foldLine.range, 0, 15, 0, 20);
  605. assert.range(fold.range, 0, 15, 0, 20);
  606. undoManager.undo(); // 1
  607. assert.range(foldLine.range, 0, 14, 0, 19);
  608. assert.range(fold.range, 0, 14, 0, 19);
  609. undoManager.undo(); // 0
  610. assert.range(foldLine.range, 0, 13, 0, 18);
  611. assert.range(fold.range, 0, 13, 0, 18);
  612. },
  613. "test fold multi-line insert/remove": function() {
  614. var session = createFoldTestSession(),
  615. undoManager = session.getUndoManager(),
  616. foldLines = session.$foldData;
  617. function insert(row, column, text) {
  618. session.insert({row: row, column: column}, text);
  619. // Force the session to store all changes made to the document NOW
  620. // on the undoManager's queue. Otherwise we can't undo in separate
  621. // steps later.
  622. session.$syncInformUndoManager();
  623. }
  624. var foldLines = session.$foldData, foldLine, fold, folds;
  625. insert(0, 0, "\nfo0");
  626. assert.equal(foldLines.length, 2);
  627. assert.range(foldLines[0].range, 1, 16, 1, 21);
  628. assert.range(foldLines[1].range, 2, 10, 3, 25);
  629. insert(2, 0, "\nba1");
  630. assert.equal(foldLines.length, 2);
  631. assert.range(foldLines[0].range, 1, 16, 1, 21);
  632. assert.range(foldLines[1].range, 3, 13, 4, 25);
  633. insert(3, 10, "\nfo2");
  634. assert.equal(foldLines.length, 2);
  635. assert.range(foldLines[0].range, 1, 16, 1, 21);
  636. assert.range(foldLines[1].range, 4, 6, 5, 25);
  637. insert(5, 10, "\nba3");
  638. assert.equal(foldLines.length, 3);
  639. assert.range(foldLines[0].range, 1, 16, 1, 21);
  640. assert.range(foldLines[1].range, 4, 6, 5, 10);
  641. assert.range(foldLines[2].range, 6, 13, 6, 18);
  642. insert(6, 18, "\nfo4");
  643. assert.equal(foldLines.length, 3);
  644. assert.range(foldLines[0].range, 1, 16, 1, 21);
  645. assert.range(foldLines[1].range, 4, 6, 5, 10);
  646. assert.range(foldLines[2].range, 6, 13, 6, 18);
  647. undoManager.undo(); // 3
  648. assert.equal(foldLines.length, 3);
  649. assert.range(foldLines[0].range, 1, 16, 1, 21);
  650. assert.range(foldLines[1].range, 4, 6, 5, 10);
  651. assert.range(foldLines[2].range, 6, 13, 6, 18);
  652. undoManager.undo(); // 2
  653. assert.equal(foldLines.length, 2);
  654. assert.range(foldLines[0].range, 1, 16, 1, 21);
  655. assert.range(foldLines[1].range, 4, 6, 5, 25);
  656. undoManager.undo(); // 1
  657. assert.equal(foldLines.length, 2);
  658. assert.range(foldLines[0].range, 1, 16, 1, 21);
  659. assert.range(foldLines[1].range, 3, 13, 4, 25);
  660. undoManager.undo(); // 0
  661. assert.equal(foldLines.length, 2);
  662. assert.range(foldLines[0].range, 1, 16, 1, 21);
  663. assert.range(foldLines[1].range, 2, 10, 3, 25);
  664. undoManager.undo(); // Beginning
  665. assert.equal(foldLines.length, 2);
  666. assert.range(foldLines[0].range, 0, 13, 0, 18);
  667. assert.range(foldLines[1].range, 1, 10, 2, 25);
  668. // TODO: Add test for inseration inside of folds.
  669. },
  670. "test fold wrap data compution": function() {
  671. function assertWrap(line0, line1, line2) {
  672. line0 && assertArray(wrapData[0], line0);
  673. line1 && assertArray(wrapData[1], line1);
  674. line2 && assertArray(wrapData[2], line2);
  675. }
  676. function removeFoldAssertWrap(docRow, docColumn, line0, line1, line2) {
  677. session.removeFold(session.getFoldAt(docRow, docColumn));
  678. assertWrap(line0, line1, line2);
  679. }
  680. var lines = [
  681. "foo bar foo bar",
  682. "foo bar foo bar",
  683. "foo bar foo bar"
  684. ];
  685. var session = new EditSession(lines.join("\n"));
  686. session.setUseWrapMode(true);
  687. session.$wrapLimit = 7;
  688. session.$updateWrapData(0, 2);
  689. var wrapData = session.$wrapData;
  690. // Do a simple assertion without folds to check basic functionallity.
  691. assertWrap([8], [8], [8]);
  692. // --- Do in line folding ---
  693. // Adding a fold. The split position is inside of the fold. As placeholder
  694. // are not splitable, the split should be before the split.
  695. session.addFold("woot", new Range(0, 4, 0, 15));
  696. assertWrap([4], [8], [8]);
  697. // Remove the fold again which should reset the wrapData.
  698. removeFoldAssertWrap(0, 4, [8], [8], [8]);
  699. session.addFold("woot", new Range(0, 6, 0, 9));
  700. assertWrap([6, 13], [8], [8]);
  701. removeFoldAssertWrap(0, 6, [8], [8], [8]);
  702. // The fold fits into the wrap limit - no split expected.
  703. session.addFold("woot", new Range(0, 3, 0, 15));
  704. assertWrap([], [8], [8]);
  705. removeFoldAssertWrap(0, 4, [8], [8], [8]);
  706. // Fold after split position should be all fine.
  707. session.addFold("woot", new Range(0, 8, 0, 15));
  708. assertWrap([8], [8], [8]);
  709. removeFoldAssertWrap(0, 8, [8], [8], [8]);
  710. // Fold's placeholder is far too long for wrapSplit.
  711. session.addFold("woot0123456789", new Range(0, 8, 0, 15));
  712. assertWrap([8], [8], [8]);
  713. removeFoldAssertWrap(0, 8, [8], [8], [8]);
  714. // Fold's placeholder is far too long for wrapSplit
  715. // + content at the end of the line
  716. session.addFold("woot0123456789", new Range(0, 6, 0, 8));
  717. assertWrap([6, 20], [8], [8]);
  718. removeFoldAssertWrap(0, 8, [8], [8], [8]);
  719. session.addFold("woot0123456789", new Range(0, 6, 0, 8));
  720. session.addFold("woot0123456789", new Range(0, 8, 0, 10));
  721. assertWrap([6, 20, 34], [8], [8]);
  722. session.removeFold(session.getFoldAt(0, 7));
  723. removeFoldAssertWrap(0, 8, [8], [8], [8]);
  724. session.addFold("woot0123456789", new Range(0, 7, 0, 9));
  725. session.addFold("woot0123456789", new Range(0, 13, 0, 15));
  726. assertWrap([7, 21, 25], [8], [8]);
  727. session.removeFold(session.getFoldAt(0, 7));
  728. removeFoldAssertWrap(0, 14, [8], [8], [8]);
  729. // --- Do some multiline folding ---
  730. // Add a fold over two lines. Note, that the wrapData[1] stays the
  731. // same. This is an implementation detail and expected behavior.
  732. session.addFold("woot", new Range(0, 8, 1, 15));
  733. assertWrap([8], [8 /* See comments */], [8]);
  734. removeFoldAssertWrap(0, 8, [8], [8], [8]);
  735. session.addFold("woot", new Range(0, 9, 1, 11));
  736. assertWrap([8, 14], [8 /* See comments */], [8]);
  737. removeFoldAssertWrap(0, 9, [8], [8], [8]);
  738. session.addFold("woot", new Range(0, 9, 1, 15));
  739. assertWrap([8], [8 /* See comments */], [8]);
  740. removeFoldAssertWrap(0, 9, [8], [8], [8]);
  741. return session;
  742. },
  743. "test delete fold with wrap enabled": function() {
  744. var session = new EditSession("");
  745. session.setValue([
  746. "This is some placeholder text that will be folded inline.",
  747. "This is some placeholder text that will be folded inline.",
  748. "More text.",
  749. "<p>The cursor in this paragraph text will be offset by 1 row.<p>",
  750. "<p>Everything after this will be offset as well due to the folds in the row before too.</p>"
  751. ].join("\n"));
  752. session.addFold('...', new Range(0, 8, 0, 42));
  753. session.addFold('...', new Range(1, 8, 1, 42));
  754. session.addFold('...', new Range(3, 7, 3, 51));
  755. session.setOption("wrap", 40);
  756. session.remove(new Range(0,0, 2, 5));
  757. // needed because adjustWrapLimit is called async from renderer
  758. session.adjustWrapLimit(80);
  759. assert.equal(session.$wrapData + "", [[], [], [40, 76]] + "");
  760. },
  761. "test add fold": function() {
  762. var session = createFoldTestSession();
  763. var fold;
  764. function tryAddFold(placeholder, range, shouldFail) {
  765. var fail = false;
  766. try {
  767. fold = session.addFold(placeholder, range);
  768. } catch (e) {
  769. fail = true;
  770. }
  771. if (fail != shouldFail) {
  772. throw new Error("Expected to get an exception");
  773. }
  774. }
  775. tryAddFold("foo", new Range(0, 13, 0, 17), false);
  776. tryAddFold("foo", new Range(0, 14, 0, 18), true);
  777. tryAddFold("foo", new Range(0, 13, 0, 18), false);
  778. assert.equal(session.$foldData[0].folds.length, 1);
  779. tryAddFold("f", new Range(0, 13, 0, 18), false);
  780. tryAddFold("foo", new Range(0, 18, 0, 21), false);
  781. assert.equal(session.$foldData[0].folds.length, 2);
  782. session.removeFold(fold);
  783. tryAddFold("foo", new Range(0, 18, 0, 22), false);
  784. tryAddFold("foo", new Range(0, 18, 0, 19), true);
  785. tryAddFold("foo", new Range(0, 22, 1, 10), false);
  786. },
  787. "test add subfolds": function() {
  788. var session = createFoldTestSession();
  789. var fold, oldFold;
  790. var foldData = session.$foldData;
  791. oldFold = foldData[0].folds[0];
  792. fold = session.addFold("fold0", new Range(0, 10, 0, 21));
  793. assert.equal(foldData[0].folds.length, 1);
  794. assert.equal(fold.subFolds.length, 1);
  795. assert.equal(fold.subFolds[0], oldFold);
  796. session.expandFold(fold);
  797. assert.equal(foldData[0].folds.length, 1);
  798. assert.equal(foldData[0].folds[0], oldFold);
  799. assert.equal(fold.subFolds.length, 0);
  800. fold = session.addFold("fold0", new Range(0, 13, 2, 10));
  801. assert.equal(foldData.length, 1);
  802. assert.equal(fold.subFolds.length, 2);
  803. assert.equal(fold.subFolds[0], oldFold);
  804. session.expandFold(fold);
  805. assert.equal(foldData.length, 2);
  806. assert.equal(foldData[0].folds.length, 1);
  807. assert.equal(foldData[0].folds[0], oldFold);
  808. assert.equal(fold.subFolds.length, 0);
  809. session.unfold(null, true);
  810. fold = session.addFold("fold0", new Range(0, 0, 0, 21));
  811. session.addFold("fold0", new Range(0, 1, 0, 5));
  812. session.addFold("fold0", new Range(0, 6, 0, 8));
  813. assert.equal(fold.subFolds.length, 2);
  814. },
  815. "test row cache": function() {
  816. var session = createFoldTestSession();
  817. session.screenToDocumentPosition(2,3);
  818. assertArray(session.$docRowCache, [1,3]);
  819. assertArray(session.$screenRowCache, [1,2]);
  820. session.screenToDocumentPosition(5,3);
  821. assertArray(session.$docRowCache, [1,3,4]);
  822. assertArray(session.$screenRowCache, [1,2,3]);
  823. session.screenToDocumentPosition(0,3);
  824. assertArray(session.$docRowCache, [1,3,4]);
  825. assertArray(session.$screenRowCache, [1,2,3]);
  826. var pos = session.screenToDocumentPosition(0,0);
  827. assert.equal(pos.row, 0);
  828. assertArray(session.$docRowCache, [1,3,4]);
  829. assertArray(session.$screenRowCache, [1,2,3]);
  830. session.screenToDocumentPosition(1,0);
  831. assertArray(session.$docRowCache, [1,3,4]);
  832. assertArray(session.$screenRowCache, [1,2,3]);
  833. session.$resetRowCache();
  834. assertArray(session.$docRowCache, []);
  835. assertArray(session.$screenRowCache, []);
  836. session.screenToDocumentPosition(1,3);
  837. assertArray(session.$docRowCache, [1]);
  838. assertArray(session.$screenRowCache, [1]);
  839. session.screenToDocumentPosition(5,3);
  840. assertArray(session.$docRowCache, [1,3,4]);
  841. assertArray(session.$screenRowCache, [1,2,3]);
  842. session = new EditSession(new Array(30).join("\n"));
  843. session.documentToScreenPosition(2,0);
  844. session.documentToScreenPosition(2,0);
  845. assertArray(session.$docRowCache, [1,2]);
  846. assertArray(session.$screenRowCache, [1,2]);
  847. },
  848. "test annotations": function() {
  849. var session = new EditSession([]),
  850. annotation = {row: 0, type: 'info', text: "This is a test."};
  851. session.clearAnnotations();
  852. assertArray(session.getAnnotations(), []);
  853. session.setAnnotations([annotation]);
  854. assertArray(session.getAnnotations(), [annotation]);
  855. },
  856. "test: mode loading" : function(next) {
  857. if (!require.undef) {
  858. console.log("Skipping test: This test only runs in the browser");
  859. next();
  860. return;
  861. }
  862. var session = new EditSession([]);
  863. session.setMode("ace/mode/javascript");
  864. assert.equal(session.$modeid, "ace/mode/javascript");
  865. session.on("changeMode", function() {
  866. assert.equal(session.$modeid, "ace/mode/javascript");
  867. });
  868. session.setMode("ace/mode/sh", function(mode) {
  869. assert.ok(!mode);
  870. });
  871. setTimeout(function() {
  872. session.setMode("ace/mode/javascript", function(mode) {
  873. session.setMode("ace/mode/javascript");
  874. assert.equal(session.$modeid, "ace/mode/javascript");
  875. next();
  876. });
  877. }, 0);
  878. }
  879. };
  880. });
  881. if (typeof module !== "undefined" && module === require.main) {
  882. require("asyncjs").test.testcase(module.exports).exec();
  883. }