test.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. (function () {
  4. var mode = CodeMirror.getMode({indentUnit: 2}, "clojure");
  5. function MT(name) {
  6. test.mode(name, mode, Array.prototype.slice.call(arguments, 1));
  7. }
  8. MT("atoms",
  9. "[atom false]",
  10. "[atom nil]",
  11. "[atom true]"
  12. );
  13. MT("keywords",
  14. "[atom :foo]",
  15. "[atom ::bar]",
  16. "[atom :foo/bar]",
  17. "[atom :foo.bar/baz]"
  18. );
  19. MT("numbers",
  20. "[number 42] [number +42] [number -421]",
  21. "[number 42N] [number +42N] [number -42N]",
  22. "[number 0.42] [number +0.42] [number -0.42]",
  23. "[number 42M] [number +42M] [number -42M]",
  24. "[number 42.42M] [number +42.42M] [number -42.42M]",
  25. "[number 1/42] [number +1/42] [number -1/42]",
  26. "[number 0x42af] [number +0x42af] [number -0x42af]",
  27. "[number 0x42AF] [number +0x42AF] [number -0x42AF]",
  28. "[number 1e2] [number 1e+2] [number 1e-2]",
  29. "[number +1e2] [number +1e+2] [number +1e-2]",
  30. "[number -1e2] [number -1e+2] [number -1e-2]",
  31. "[number -1.0e2] [number -0.1e+2] [number -1.01e-2]",
  32. "[number 1E2] [number 1E+2] [number 1E-2]",
  33. "[number +1E2] [number +1E+2] [number +1E-2]",
  34. "[number -1E2] [number -1E+2] [number -1E-2]",
  35. "[number -1.0E2] [number -0.1E+2] [number -1.01E-2]",
  36. "[number 2r101010] [number +2r101010] [number -2r101010]",
  37. "[number 2r101010] [number +2r101010] [number -2r101010]",
  38. "[number 8r52] [number +8r52] [number -8r52]",
  39. "[number 36rhello] [number +36rhello] [number -36rhello]",
  40. "[number 36rz] [number +36rz] [number -36rz]",
  41. "[number 36rZ] [number +36rZ] [number -36rZ]",
  42. // invalid numbers
  43. "[error 42foo]",
  44. "[error 42Nfoo]",
  45. "[error 42Mfoo]",
  46. "[error 42.42Mfoo]",
  47. "[error 42.42M!]",
  48. "[error 42!]",
  49. "[error 0x42afm]"
  50. );
  51. MT("characters",
  52. "[string-2 \\1]",
  53. "[string-2 \\a]",
  54. "[string-2 \\a\\b\\c]",
  55. "[string-2 \\#]",
  56. "[string-2 \\\\]",
  57. "[string-2 \\\"]",
  58. "[string-2 \\(]",
  59. "[string-2 \\A]",
  60. "[string-2 \\backspace]",
  61. "[string-2 \\formfeed]",
  62. "[string-2 \\newline]",
  63. "[string-2 \\space]",
  64. "[string-2 \\return]",
  65. "[string-2 \\tab]",
  66. "[string-2 \\u1000]",
  67. "[string-2 \\uAaAa]",
  68. "[string-2 \\u9F9F]",
  69. "[string-2 \\o123]",
  70. "[string-2 \\符]",
  71. "[string-2 \\シ]",
  72. "[string-2 \\ۇ]",
  73. // FIXME
  74. // "[string-2 \\🙂]",
  75. // invalid character literals
  76. "[error \\abc]",
  77. "[error \\a123]",
  78. "[error \\a!]",
  79. "[error \\newlines]",
  80. "[error \\NEWLINE]",
  81. "[error \\u9F9FF]",
  82. "[error \\o1234]"
  83. );
  84. MT("strings",
  85. "[string \"I'm a teapot.\"]",
  86. "[string \"I'm a \\\"teapot\\\".\"]",
  87. "[string \"I'm]", // this is
  88. "[string a]", // a multi-line
  89. "[string teapot.\"]" // string
  90. // TODO unterminated (multi-line) strings?
  91. );
  92. MT("comments",
  93. "[comment ; this is an in-line comment.]",
  94. "[comment ;; this is a line comment.]",
  95. "[keyword comment]",
  96. "[bracket (][comment comment (foo 1 2 3)][bracket )]"
  97. );
  98. MT("reader macro characters",
  99. "[meta #][variable _]",
  100. "[meta #][variable -Inf]",
  101. "[meta ##][variable Inf]",
  102. "[meta ##][variable NaN]",
  103. "[meta @][variable x]",
  104. "[meta ^][bracket {][atom :tag] [variable String][bracket }]",
  105. "[meta `][bracket (][builtin f] [variable x][bracket )]",
  106. "[meta ~][variable foo#]",
  107. "[meta '][number 1]",
  108. "[meta '][atom :foo]",
  109. "[meta '][string \"foo\"]",
  110. "[meta '][variable x]",
  111. "[meta '][bracket (][builtin a] [variable b] [variable c][bracket )]",
  112. "[meta '][bracket [[][variable a] [variable b] [variable c][bracket ]]]",
  113. "[meta '][bracket {][variable a] [number 1] [atom :foo] [number 2] [variable c] [number 3][bracket }]",
  114. "[meta '#][bracket {][variable a] [number 1] [atom :foo][bracket }]"
  115. );
  116. MT("symbols",
  117. "[variable foo!]",
  118. "[variable foo#]",
  119. "[variable foo$]",
  120. "[variable foo&]",
  121. "[variable foo']",
  122. "[variable foo*]",
  123. "[variable foo+]",
  124. "[variable foo-]",
  125. "[variable foo.]",
  126. "[variable foo/bar]",
  127. "[variable foo:bar]",
  128. "[variable foo<]",
  129. "[variable foo=]",
  130. "[variable foo>]",
  131. "[variable foo?]",
  132. "[variable foo_]",
  133. "[variable foo|]",
  134. "[variable foobarBaz]",
  135. "[variable foo¡]",
  136. "[variable 符号]",
  137. "[variable シンボル]",
  138. "[variable ئۇيغۇر]",
  139. "[variable 🙂❤🇺🇸]",
  140. // invalid symbols
  141. "[error 3foo]",
  142. "[error 3+]",
  143. "[error 3|]",
  144. "[error 3_]"
  145. );
  146. MT("numbers and other forms",
  147. "[number 42][bracket (][builtin foo][bracket )]",
  148. "[number 42][bracket [[][variable foo][bracket ]]]",
  149. "[number 42][meta #][bracket {][variable foo][bracket }]",
  150. "[number 42][bracket {][atom :foo] [variable bar][bracket }]",
  151. "[number 42][meta `][variable foo]",
  152. "[number 42][meta ~][variable foo]",
  153. "[number 42][meta #][variable foo]"
  154. );
  155. var specialForms = [".", "catch", "def", "do", "if", "monitor-enter",
  156. "monitor-exit", "new", "quote", "recur", "set!", "throw", "try", "var"];
  157. MT("should highlight special forms as keywords",
  158. typeTokenPairs("keyword", specialForms)
  159. );
  160. var coreSymbols1 = [
  161. "*", "*'", "*1", "*2", "*3", "*agent*", "*allow-unresolved-vars*", "*assert*",
  162. "*clojure-version*", "*command-line-args*", "*compile-files*", "*compile-path*", "*compiler-options*",
  163. "*data-readers*", "*default-data-reader-fn*", "*e", "*err*", "*file*", "*flush-on-newline*", "*fn-loader*",
  164. "*in*", "*math-context*", "*ns*", "*out*", "*print-dup*", "*print-length*", "*print-level*", "*print-meta*",
  165. "*print-namespace-maps*", "*print-readably*", "*read-eval*", "*reader-resolver*", "*source-path*",
  166. "*suppress-read*", "*unchecked-math*", "*use-context-classloader*", "*verbose-defrecords*",
  167. "*warn-on-reflection*", "+", "+'", "-", "-'", "->", "->>", "->ArrayChunk", "->Eduction", "->Vec", "->VecNode",
  168. "->VecSeq", "-cache-protocol-fn", "-reset-methods", "..", "/", "<", "<=", "=", "==", ">", ">=",
  169. "EMPTY-NODE", "Inst", "StackTraceElement->vec", "Throwable->map", "accessor", "aclone", "add-classpath",
  170. "add-watch", "agent", "agent-error", "agent-errors", "aget", "alength", "alias", "all-ns", "alter",
  171. "alter-meta!", "alter-var-root", "amap", "ancestors", "and", "any?", "apply", "areduce", "array-map",
  172. "as->", "aset", "aset-boolean", "aset-byte", "aset-char", "aset-double", "aset-float", "aset-int",
  173. "aset-long", "aset-short", "assert", "assoc", "assoc!", "assoc-in", "associative?", "atom", "await",
  174. "await-for", "await1", "bases", "bean", "bigdec", "bigint", "biginteger", "binding", "bit-and", "bit-and-not",
  175. "bit-clear", "bit-flip", "bit-not", "bit-or", "bit-set", "bit-shift-left", "bit-shift-right", "bit-test",
  176. "bit-xor", "boolean", "boolean-array", "boolean?", "booleans", "bound-fn", "bound-fn*", "bound?",
  177. "bounded-count", "butlast", "byte", "byte-array", "bytes", "bytes?", "case", "cast", "cat", "char",
  178. "char-array", "char-escape-string", "char-name-string", "char?", "chars", "chunk", "chunk-append",
  179. "chunk-buffer", "chunk-cons", "chunk-first", "chunk-next", "chunk-rest", "chunked-seq?", "class", "class?",
  180. "clear-agent-errors", "clojure-version", "coll?", "comment", "commute", "comp", "comparator", "compare",
  181. "compare-and-set!", "compile", "complement", "completing", "concat", "cond", "cond->", "cond->>", "condp",
  182. "conj", "conj!", "cons", "constantly", "construct-proxy", "contains?", "count", "counted?", "create-ns",
  183. "create-struct", "cycle", "dec", "dec'", "decimal?", "declare", "dedupe", "default-data-readers", "definline",
  184. "definterface", "defmacro", "defmethod", "defmulti", "defn", "defn-", "defonce", "defprotocol", "defrecord",
  185. "defstruct", "deftype", "delay", "delay?", "deliver", "denominator", "deref", "derive", "descendants",
  186. "destructure", "disj", "disj!", "dissoc", "dissoc!", "distinct", "distinct?", "doall", "dorun", "doseq",
  187. "dosync", "dotimes", "doto", "double", "double-array", "double?", "doubles", "drop", "drop-last", "drop-while",
  188. "eduction", "empty", "empty?", "ensure", "ensure-reduced", "enumeration-seq", "error-handler", "error-mode",
  189. "eval", "even?", "every-pred", "every?", "ex-data", "ex-info", "extend", "extend-protocol", "extend-type",
  190. "extenders", "extends?", "false?", "ffirst", "file-seq", "filter", "filterv", "find", "find-keyword", "find-ns",
  191. "find-protocol-impl", "find-protocol-method", "find-var", "first", "flatten", "float", "float-array", "float?",
  192. "floats", "flush", "fn", "fn?", "fnext", "fnil", "for", "force", "format", "frequencies", "future", "future-call",
  193. "future-cancel", "future-cancelled?", "future-done?", "future?", "gen-class", "gen-interface", "gensym", "get",
  194. "get-in", "get-method", "get-proxy-class", "get-thread-bindings", "get-validator", "group-by", "halt-when", "hash",
  195. "hash-combine", "hash-map", "hash-ordered-coll", "hash-set", "hash-unordered-coll", "ident?", "identical?",
  196. "identity", "if-let", "if-not", "if-some", "ifn?", "import", "in-ns", "inc", "inc'", "indexed?", "init-proxy",
  197. "inst-ms", "inst-ms*", "inst?", "instance?", "int", "int-array", "int?", "integer?", "interleave", "intern",
  198. "interpose", "into", "into-array", "ints", "io!", "isa?", "iterate", "iterator-seq", "juxt", "keep", "keep-indexed",
  199. "key", "keys", "keyword", "keyword?", "last", "lazy-cat", "lazy-seq", "let", "letfn", "line-seq", "list", "list*",
  200. "list?", "load", "load-file", "load-reader", "load-string", "loaded-libs", "locking", "long", "long-array", "longs",
  201. "loop", "macroexpand", "macroexpand-1", "make-array", "make-hierarchy", "map", "map-entry?", "map-indexed", "map?",
  202. "mapcat", "mapv", "max", "max-key", "memfn", "memoize", "merge", "merge-with", "meta", "method-sig", "methods"];
  203. var coreSymbols2 = [
  204. "min", "min-key", "mix-collection-hash", "mod", "munge", "name", "namespace", "namespace-munge", "nat-int?",
  205. "neg-int?", "neg?", "newline", "next", "nfirst", "nil?", "nnext", "not", "not-any?", "not-empty", "not-every?",
  206. "not=", "ns", "ns-aliases", "ns-imports", "ns-interns", "ns-map", "ns-name", "ns-publics", "ns-refers", "ns-resolve",
  207. "ns-unalias", "ns-unmap", "nth", "nthnext", "nthrest", "num", "number?", "numerator", "object-array", "odd?", "or",
  208. "parents", "partial", "partition", "partition-all", "partition-by", "pcalls", "peek", "persistent!", "pmap", "pop",
  209. "pop!", "pop-thread-bindings", "pos-int?", "pos?", "pr", "pr-str", "prefer-method", "prefers",
  210. "primitives-classnames", "print", "print-ctor", "print-dup", "print-method", "print-simple", "print-str", "printf",
  211. "println", "println-str", "prn", "prn-str", "promise", "proxy", "proxy-call-with-super", "proxy-mappings",
  212. "proxy-name", "proxy-super", "push-thread-bindings", "pvalues", "qualified-ident?", "qualified-keyword?",
  213. "qualified-symbol?", "quot", "rand", "rand-int", "rand-nth", "random-sample", "range", "ratio?", "rational?",
  214. "rationalize", "re-find", "re-groups", "re-matcher", "re-matches", "re-pattern", "re-seq", "read", "read-line",
  215. "read-string", "reader-conditional", "reader-conditional?", "realized?", "record?", "reduce", "reduce-kv", "reduced",
  216. "reduced?", "reductions", "ref", "ref-history-count", "ref-max-history", "ref-min-history", "ref-set", "refer",
  217. "refer-clojure", "reify", "release-pending-sends", "rem", "remove", "remove-all-methods", "remove-method", "remove-ns",
  218. "remove-watch", "repeat", "repeatedly", "replace", "replicate", "require", "reset!", "reset-meta!", "reset-vals!",
  219. "resolve", "rest", "restart-agent", "resultset-seq", "reverse", "reversible?", "rseq", "rsubseq", "run!", "satisfies?",
  220. "second", "select-keys", "send", "send-off", "send-via", "seq", "seq?", "seqable?", "seque", "sequence", "sequential?",
  221. "set", "set-agent-send-executor!", "set-agent-send-off-executor!", "set-error-handler!", "set-error-mode!",
  222. "set-validator!", "set?", "short", "short-array", "shorts", "shuffle", "shutdown-agents", "simple-ident?",
  223. "simple-keyword?", "simple-symbol?", "slurp", "some", "some->", "some->>", "some-fn", "some?", "sort", "sort-by",
  224. "sorted-map", "sorted-map-by", "sorted-set", "sorted-set-by", "sorted?", "special-symbol?", "spit", "split-at",
  225. "split-with", "str", "string?", "struct", "struct-map", "subs", "subseq", "subvec", "supers", "swap!", "swap-vals!",
  226. "symbol", "symbol?", "sync", "tagged-literal", "tagged-literal?", "take", "take-last", "take-nth", "take-while", "test",
  227. "the-ns", "thread-bound?", "time", "to-array", "to-array-2d", "trampoline", "transduce", "transient", "tree-seq",
  228. "true?", "type", "unchecked-add", "unchecked-add-int", "unchecked-byte", "unchecked-char", "unchecked-dec",
  229. "unchecked-dec-int", "unchecked-divide-int", "unchecked-double", "unchecked-float", "unchecked-inc", "unchecked-inc-int",
  230. "unchecked-int", "unchecked-long", "unchecked-multiply", "unchecked-multiply-int", "unchecked-negate",
  231. "unchecked-negate-int", "unchecked-remainder-int", "unchecked-short", "unchecked-subtract", "unchecked-subtract-int",
  232. "underive", "unquote", "unquote-splicing", "unreduced", "unsigned-bit-shift-right", "update", "update-in",
  233. "update-proxy", "uri?", "use", "uuid?", "val", "vals", "var-get", "var-set", "var?", "vary-meta", "vec", "vector",
  234. "vector-of", "vector?", "volatile!", "volatile?", "vreset!", "vswap!", "when", "when-first", "when-let", "when-not",
  235. "when-some", "while", "with-bindings", "with-bindings*", "with-in-str", "with-loading-context", "with-local-vars",
  236. "with-meta", "with-open", "with-out-str", "with-precision", "with-redefs", "with-redefs-fn", "xml-seq", "zero?",
  237. "zipmap"
  238. ];
  239. MT("should highlight core symbols as keywords (part 1/2)",
  240. typeTokenPairs("keyword", coreSymbols1)
  241. );
  242. MT("should highlight core symbols as keywords (part 2/2)",
  243. typeTokenPairs("keyword", coreSymbols2)
  244. );
  245. MT("should properly indent forms in list literals",
  246. "[bracket (][builtin foo] [atom :a] [number 1] [atom true] [atom nil][bracket )]",
  247. "",
  248. "[bracket (][builtin foo] [atom :a]",
  249. " [number 1]",
  250. " [atom true]",
  251. " [atom nil][bracket )]",
  252. "",
  253. "[bracket (][builtin foo] [atom :a] [number 1]",
  254. " [atom true]",
  255. " [atom nil][bracket )]",
  256. "",
  257. "[bracket (]",
  258. " [builtin foo]",
  259. " [atom :a]",
  260. " [number 1]",
  261. " [atom true]",
  262. " [atom nil][bracket )]",
  263. "",
  264. "[bracket (][builtin foo] [bracket [[][atom :a][bracket ]]]",
  265. " [number 1]",
  266. " [atom true]",
  267. " [atom nil][bracket )]"
  268. );
  269. MT("should properly indent forms in vector literals",
  270. "[bracket [[][atom :a] [number 1] [atom true] [atom nil][bracket ]]]",
  271. "",
  272. "[bracket [[][atom :a]",
  273. " [number 1]",
  274. " [atom true]",
  275. " [atom nil][bracket ]]]",
  276. "",
  277. "[bracket [[][atom :a] [number 1]",
  278. " [atom true]",
  279. " [atom nil][bracket ]]]",
  280. "",
  281. "[bracket [[]",
  282. " [variable foo]",
  283. " [atom :a]",
  284. " [number 1]",
  285. " [atom true]",
  286. " [atom nil][bracket ]]]"
  287. );
  288. MT("should properly indent forms in map literals",
  289. "[bracket {][atom :a] [atom :a] [atom :b] [number 1] [atom :c] [atom true] [atom :d] [atom nil] [bracket }]",
  290. "",
  291. "[bracket {][atom :a] [atom :a]",
  292. " [atom :b] [number 1]",
  293. " [atom :c] [atom true]",
  294. " [atom :d] [atom nil][bracket }]",
  295. "",
  296. "[bracket {][atom :a]",
  297. " [atom :a]",
  298. " [atom :b]",
  299. " [number 1]",
  300. " [atom :c]",
  301. " [atom true]",
  302. " [atom :d]",
  303. " [atom nil][bracket }]",
  304. "",
  305. "[bracket {]",
  306. " [atom :a] [atom :a]",
  307. " [atom :b] [number 1]",
  308. " [atom :c] [atom true]",
  309. " [atom :d] [atom nil][bracket }]"
  310. );
  311. MT("should properly indent forms in set literals",
  312. "[meta #][bracket {][atom :a] [number 1] [atom true] [atom nil] [bracket }]",
  313. "",
  314. "[meta #][bracket {][atom :a]",
  315. " [number 1]",
  316. " [atom true]",
  317. " [atom nil][bracket }]",
  318. "",
  319. "[meta #][bracket {]",
  320. " [atom :a]",
  321. " [number 1]",
  322. " [atom true]",
  323. " [atom nil][bracket }]"
  324. );
  325. var haveBodyParameter = [
  326. "->", "->>", "as->", "binding", "bound-fn", "case", "catch", "cond",
  327. "cond->", "cond->>", "condp", "def", "definterface", "defmethod", "defn",
  328. "defmacro", "defprotocol", "defrecord", "defstruct", "deftype", "do",
  329. "doseq", "dotimes", "doto", "extend", "extend-protocol", "extend-type",
  330. "fn", "for", "future", "if", "if-let", "if-not", "if-some", "let",
  331. "letfn", "locking", "loop", "ns", "proxy", "reify", "some->", "some->>",
  332. "struct-map", "try", "when", "when-first", "when-let", "when-not",
  333. "when-some", "while", "with-bindings", "with-bindings*", "with-in-str",
  334. "with-loading-context", "with-local-vars", "with-meta", "with-open",
  335. "with-out-str", "with-precision", "with-redefs", "with-redefs-fn"];
  336. function testFormsThatHaveBodyParameter(forms) {
  337. for (var i = 0; i < forms.length; i++) {
  338. MT("should indent body argument of `" + forms[i] + "` by `options.indentUnit` spaces",
  339. "[bracket (][keyword " + forms[i] + "] [variable foo] [variable bar]",
  340. " [variable baz]",
  341. " [variable qux][bracket )]"
  342. );
  343. }
  344. }
  345. testFormsThatHaveBodyParameter(haveBodyParameter);
  346. MT("should indent body argument of `comment` by `options.indentUnit` spaces",
  347. "[bracket (][comment comment foo bar]",
  348. "[comment baz]",
  349. "[comment qux][bracket )]"
  350. );
  351. function typeTokenPairs(type, tokens) {
  352. return "[" + type + " " + tokens.join("] [" + type + " ") + "]";
  353. }
  354. })();