test.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. var tests = [];
  2. test("fromTextArea", function() {
  3. var te = document.getElementById("code");
  4. te.value = "CONTENT";
  5. var cm = CodeMirror.fromTextArea(te);
  6. is(!te.offsetHeight);
  7. eq(cm.getValue(), "CONTENT");
  8. cm.setValue("foo\nbar");
  9. eq(cm.getValue(), "foo\nbar");
  10. cm.save();
  11. is(/^foo\r?\nbar$/.test(te.value));
  12. cm.setValue("xxx");
  13. cm.toTextArea();
  14. is(te.offsetHeight);
  15. eq(te.value, "xxx");
  16. });
  17. testCM("getRange", function(cm) {
  18. eq(cm.getLine(0), "1234");
  19. eq(cm.getLine(1), "5678");
  20. eq(cm.getLine(2), null);
  21. eq(cm.getLine(-1), null);
  22. eq(cm.getRange({line: 0, ch: 0}, {line: 0, ch: 3}), "123");
  23. eq(cm.getRange({line: 0, ch: -1}, {line: 0, ch: 200}), "1234");
  24. eq(cm.getRange({line: 0, ch: 2}, {line: 1, ch: 2}), "34\n56");
  25. eq(cm.getRange({line: 1, ch: 2}, {line: 100, ch: 0}), "78");
  26. }, {value: "1234\n5678"});
  27. testCM("replaceRange", function(cm) {
  28. eq(cm.getValue(), "");
  29. cm.replaceRange("foo\n", {line: 0, ch: 0});
  30. eq(cm.getValue(), "foo\n");
  31. cm.replaceRange("a\nb", {line: 0, ch: 1});
  32. eq(cm.getValue(), "fa\nboo\n");
  33. eq(cm.lineCount(), 3);
  34. cm.replaceRange("xyzzy", {line: 0, ch: 0}, {line: 1, ch: 1});
  35. eq(cm.getValue(), "xyzzyoo\n");
  36. cm.replaceRange("abc", {line: 0, ch: 0}, {line: 10, ch: 0});
  37. eq(cm.getValue(), "abc");
  38. eq(cm.lineCount(), 1);
  39. });
  40. testCM("selection", function(cm) {
  41. cm.setSelection({line: 0, ch: 4}, {line: 2, ch: 2});
  42. is(cm.somethingSelected());
  43. eq(cm.getSelection(), "11\n222222\n33");
  44. eqPos(cm.getCursor(false), {line: 2, ch: 2});
  45. eqPos(cm.getCursor(true), {line: 0, ch: 4});
  46. cm.setSelection({line: 1, ch: 0});
  47. is(!cm.somethingSelected());
  48. eq(cm.getSelection(), "");
  49. eqPos(cm.getCursor(true), {line: 1, ch: 0});
  50. cm.replaceSelection("abc");
  51. eq(cm.getSelection(), "abc");
  52. eq(cm.getValue(), "111111\nabc222222\n333333");
  53. cm.replaceSelection("def", "end");
  54. eq(cm.getSelection(), "");
  55. eqPos(cm.getCursor(true), {line: 1, ch: 3});
  56. cm.setCursor({line: 2, ch: 1});
  57. eqPos(cm.getCursor(true), {line: 2, ch: 1});
  58. cm.setCursor(1, 2);
  59. eqPos(cm.getCursor(true), {line: 1, ch: 2});
  60. }, {value: "111111\n222222\n333333"});
  61. testCM("lines", function(cm) {
  62. eq(cm.getLine(0), "111111");
  63. eq(cm.getLine(1), "222222");
  64. eq(cm.getLine(-1), null);
  65. cm.removeLine(1);
  66. cm.setLine(1, "abc");
  67. eq(cm.getValue(), "111111\nabc");
  68. }, {value: "111111\n222222\n333333"});
  69. testCM("indent", function(cm) {
  70. cm.indentLine(1);
  71. eq(cm.getLine(1), " blah();");
  72. cm.setOption("indentUnit", 8);
  73. cm.indentLine(1);
  74. eq(cm.getLine(1), "\tblah();");
  75. }, {value: "if (x) {\nblah();\n}", indentUnit: 3, indentWithTabs: true});
  76. test("defaults", function() {
  77. var olddefaults = CodeMirror.defaults, defs = CodeMirror.defaults = {};
  78. for (var opt in olddefaults) defs[opt] = olddefaults[opt];
  79. defs.indentUnit = 5;
  80. defs.value = "uu";
  81. defs.enterMode = "keep";
  82. defs.tabindex = 55;
  83. var place = document.getElementById("testground"), cm = CodeMirror(place);
  84. try {
  85. eq(cm.getOption("indentUnit"), 5);
  86. cm.setOption("indentUnit", 10);
  87. eq(defs.indentUnit, 5);
  88. eq(cm.getValue(), "uu");
  89. eq(cm.getOption("enterMode"), "keep");
  90. eq(cm.getInputField().tabindex, 55);
  91. }
  92. finally {
  93. CodeMirror.defaults = olddefaults;
  94. place.removeChild(cm.getWrapperElement());
  95. }
  96. });
  97. testCM("lineInfo", function(cm) {
  98. eq(cm.lineInfo(-1), null);
  99. var lh = cm.setMarker(1, "FOO", "bar");
  100. var info = cm.lineInfo(1);
  101. eq(info.text, "222222");
  102. eq(info.markerText, "FOO");
  103. eq(info.markerClass, "bar");
  104. eq(info.line, 1);
  105. eq(cm.lineInfo(2).markerText, null);
  106. cm.clearMarker(lh);
  107. eq(cm.lineInfo(1).markerText, null);
  108. }, {value: "111111\n222222\n333333"});
  109. testCM("coords", function(cm) {
  110. var scroller = cm.getWrapperElement().getElementsByClassName("CodeMirror-scroll")[0];
  111. scroller.style.height = "100px";
  112. var content = [];
  113. for (var i = 0; i < 200; ++i) content.push("------------------------------" + i);
  114. cm.setValue(content.join("\n"));
  115. var top = cm.charCoords({line: 0, ch: 0});
  116. var bot = cm.charCoords({line: 200, ch: 30});
  117. is(top.x < bot.x);
  118. is(top.y < bot.y);
  119. is(top.y < top.yBot);
  120. scroller.scrollTop = 100;
  121. cm.refresh();
  122. var top2 = cm.charCoords({line: 0, ch: 0});
  123. is(top.y > top2.y);
  124. eq(top.x, top2.x);
  125. });
  126. testCM("coordsChar", function(cm) {
  127. var content = [];
  128. for (var i = 0; i < 70; ++i) content.push("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
  129. cm.setValue(content.join("\n"));
  130. for (var x = 0; x < 35; x += 2) {
  131. for (var y = 0; y < 70; y += 5) {
  132. cm.setCursor(y, x);
  133. var pos = cm.coordsChar(cm.charCoords({line: y, ch: x}));
  134. eq(pos.line, y);
  135. eq(pos.ch, x);
  136. }
  137. }
  138. });
  139. testCM("undo", function(cm) {
  140. cm.setLine(0, "def");
  141. eq(cm.historySize().undo, 1);
  142. cm.undo();
  143. eq(cm.getValue(), "abc");
  144. eq(cm.historySize().undo, 0);
  145. eq(cm.historySize().redo, 1);
  146. cm.redo();
  147. eq(cm.getValue(), "def");
  148. eq(cm.historySize().undo, 1);
  149. eq(cm.historySize().redo, 0);
  150. cm.setValue("1\n\n\n2");
  151. eq(cm.historySize().undo, 0);
  152. for (var i = 0; i < 20; ++i) {
  153. cm.replaceRange("a", {line: 0, ch: 0});
  154. cm.replaceRange("b", {line: 3, ch: 0});
  155. }
  156. eq(cm.historySize().undo, 40);
  157. for (var i = 0; i < 38; ++i) cm.undo();
  158. eq(cm.historySize().undo, 2);
  159. eq(cm.historySize().redo, 38);
  160. eq(cm.getValue(), "a1\n\n\nb2");
  161. cm.setOption("undoDepth", 10);
  162. for (var i = 0; i < 20; ++i) {
  163. cm.replaceRange("a", {line: 0, ch: 0});
  164. cm.replaceRange("b", {line: 3, ch: 0});
  165. }
  166. eq(cm.historySize().undo, 10);
  167. }, {value: "abc"});
  168. testCM("undoMultiLine", function(cm) {
  169. cm.replaceRange("x", {line:0, ch: 0});
  170. cm.replaceRange("y", {line:1, ch: 0});
  171. cm.undo();
  172. eq(cm.getValue(), "abc\ndef\nghi");
  173. cm.replaceRange("y", {line:1, ch: 0});
  174. cm.replaceRange("x", {line:0, ch: 0});
  175. cm.undo();
  176. eq(cm.getValue(), "abc\ndef\nghi");
  177. cm.replaceRange("y", {line:2, ch: 0});
  178. cm.replaceRange("x", {line:1, ch: 0});
  179. cm.replaceRange("z", {line:2, ch: 0});
  180. cm.undo();
  181. eq(cm.getValue(), "abc\ndef\nghi");
  182. }, {value: "abc\ndef\nghi"});
  183. // Scaffolding
  184. function htmlEscape(str) {
  185. return str.replace(/[<&]/g, function(str) {return str == "&" ? "&amp;" : "&lt;";});
  186. }
  187. function forEach(arr, f) {
  188. for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
  189. }
  190. function Failure(why) {this.message = why;}
  191. function test(name, run) {tests.push({name: name, func: run});}
  192. function testCM(name, run, opts) {
  193. test(name, function() {
  194. var place = document.getElementById("testground"), cm = CodeMirror(place, opts);
  195. try {run(cm);}
  196. finally {place.removeChild(cm.getWrapperElement());}
  197. });
  198. }
  199. function runTests() {
  200. var failures = [], run = 0;
  201. for (var i = 0; i < tests.length; ++i) {
  202. var test = tests[i];
  203. try {test.func();}
  204. catch(e) {
  205. if (e instanceof Failure)
  206. failures.push({type: "failure", test: test.name, text: e.message});
  207. else
  208. failures.push({type: "error", test: test.name, text: e.toString()});
  209. }
  210. run++;
  211. }
  212. var html = [run + " tests run."];
  213. if (failures.length)
  214. forEach(failures, function(fail) {
  215. html.push(fail.test + ': <span class="' + fail.type + '">' + htmlEscape(fail.text) + "</span>");
  216. });
  217. else html.push('<span class="ok">All passed.</span>');
  218. document.getElementById("output").innerHTML = html.join("\n");
  219. }
  220. function eq(a, b, msg) {
  221. if (a != b) throw new Failure(a + " != " + b + (msg ? " (" + msg + ")" : ""));
  222. }
  223. function eqPos(a, b, msg) {
  224. eq(a.line, b.line, msg);
  225. eq(a.ch, b.ch, msg);
  226. }
  227. function is(a, msg) {
  228. if (!a) throw new Failure("assertion failed" + (msg ? " (" + msg + ")" : ""));
  229. }
  230. window.onload = runTests;