Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 4192140

Browse files
author
Miles Richardson
committed
Add some basic specs for the grammar
1 parent fa482c3 commit 4192140

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed

spec/grammar-spec.coffee

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,180 @@ describe "Clojure grammar", ->
1212
expect(grammar).toBeDefined()
1313
expect(grammar.scopeName).toBe "source.clojure"
1414

15+
it "tokenizes semi-colon comments", ->
16+
{tokens} = grammar.tokenizeLine "; clojure"
17+
expect(tokens[0]).toEqual value: ";", scopes: ["source.clojure", "comment.line.semicolon.clojure", "punctuation.definition.comment.clojure"]
18+
expect(tokens[1]).toEqual value: " clojure", scopes: ["source.clojure", "comment.line.semicolon.clojure"]
19+
20+
it "tokenizes shebang comments", ->
21+
{tokens} = grammar.tokenizeLine "#!/usr/bin/env clojure"
22+
expect(tokens[0]).toEqual value: "#!", scopes: ["source.clojure", "comment.line.semicolon.clojure", "punctuation.definition.comment.shebang.clojure"]
23+
expect(tokens[1]).toEqual value: "/usr/bin/env clojure", scopes: ["source.clojure", "comment.line.semicolon.clojure"]
24+
25+
it "tokenizes strings", ->
26+
{tokens} = grammar.tokenizeLine '"foo bar"'
27+
expect(tokens[0]).toEqual value: '"', scopes: ["source.clojure", "string.quoted.double.clojure", "punctuation.definition.string.begin.clojure"]
28+
expect(tokens[1]).toEqual value: 'foo bar', scopes: ["source.clojure", "string.quoted.double.clojure"]
29+
expect(tokens[2]).toEqual value: '"', scopes: ["source.clojure", "string.quoted.double.clojure", "punctuation.definition.string.end.clojure"]
30+
31+
it "tokenizes character escape sequences", ->
32+
{tokens} = grammar.tokenizeLine '"\\n"'
33+
expect(tokens[0]).toEqual value: '"', scopes: ["source.clojure", "string.quoted.double.clojure", "punctuation.definition.string.begin.clojure"]
34+
expect(tokens[1]).toEqual value: '\\n', scopes: ["source.clojure", "string.quoted.double.clojure", "constant.character.escape.clojure"]
35+
expect(tokens[2]).toEqual value: '"', scopes: ["source.clojure", "string.quoted.double.clojure", "punctuation.definition.string.end.clojure"]
36+
37+
it "tokenizes regexes", ->
38+
{tokens} = grammar.tokenizeLine '#"foo"'
39+
expect(tokens[0]).toEqual value: '#"', scopes: ["source.clojure", "string.regexp.clojure"]
40+
expect(tokens[1]).toEqual value: 'foo', scopes: ["source.clojure", "string.regexp.clojure"]
41+
expect(tokens[2]).toEqual value: '"', scopes: ["source.clojure", "string.regexp.clojure"]
42+
43+
it "tokenizes numerics", ->
44+
numbers =
45+
"constant.numeric.ratio.clojure": ["1/2", "123/456"]
46+
"constant.numeric.arbitrary-radix.clojure": ["2R1011", "16rDEADBEEF"]
47+
"constant.numeric.hexadecimal.clojure": ["0xDEADBEEF", "0XDEADBEEF"]
48+
"constant.numeric.octal.clojure": ["0123"]
49+
"constant.numeric.bigdecimal.clojure": ["123.456M"]
50+
"constant.numeric.double.clojure": ["123.45", "123.45e6", "123.45E6"]
51+
"constant.numeric.bigint.clojure": ["123N"]
52+
"constant.numeric.long.clojure": ["123", "12321"]
53+
54+
for scope, nums of numbers
55+
for num in nums
56+
{tokens} = grammar.tokenizeLine num
57+
expect(tokens[0]).toEqual value: num, scopes: ["source.clojure", scope]
58+
59+
it "tokenizes booleans", ->
60+
booleans =
61+
"constant.language.boolean.clojure": ["true", "false"]
62+
63+
for scope, bools of booleans
64+
for bool in bools
65+
{tokens} = grammar.tokenizeLine bool
66+
expect(tokens[0]).toEqual value: bool, scopes: ["source.clojure", scope]
67+
68+
it "tokenizes nil", ->
69+
{tokens} = grammar.tokenizeLine "nil"
70+
expect(tokens[0]).toEqual value: "nil", scopes: ["source.clojure", "constant.language.nil.clojure"]
71+
72+
it "tokenizes keywords", ->
73+
tests =
74+
"meta.expression.clojure": ["(:foo)"]
75+
"meta.map.clojure": ["{:foo}"]
76+
"meta.vector.clojure": ["[:foo]"]
77+
"meta.quoted-expression.clojure": ["'(:foo)", "`(:foo)"]
78+
79+
for metaScope, lines of tests
80+
for line in lines
81+
{tokens} = grammar.tokenizeLine line
82+
expect(tokens[1]).toEqual value: ":foo", scopes: ["source.clojure", metaScope, "constant.keyword.clojure"]
83+
84+
it "tokenizes keyfns (keyword control)", ->
85+
keyfns = ["declare", "declare-", "ns", "in-ns", "import", "use", "require", "load", "compile", "def", "defn", "defn-", "defmacro"]
86+
87+
for keyfn in keyfns
88+
{tokens} = grammar.tokenizeLine "(#{keyfn})"
89+
expect(tokens[1]).toEqual value: keyfn, scopes: ["source.clojure", "meta.expression.clojure", "keyword.control.clojure"]
90+
91+
it "tokenizes keyfns (storage control)", ->
92+
keyfns = ["if", "when", "for", "cond", "do", "let", "binding", "loop", "recur", "fn", "throw", "try", "catch", "finally", "case"]
93+
94+
for keyfn in keyfns
95+
{tokens} = grammar.tokenizeLine "(#{keyfn})"
96+
expect(tokens[1]).toEqual value: keyfn, scopes: ["source.clojure", "meta.expression.clojure", "storage.control.clojure"]
97+
98+
it "tokenizes global definitions", ->
99+
{tokens} = grammar.tokenizeLine "(def foo 'bar)"
100+
expect(tokens[1]).toEqual value: "def", scopes: ["source.clojure", "meta.expression.clojure", "meta.definition.global.clojure", "keyword.control.clojure"]
101+
expect(tokens[3]).toEqual value: "foo", scopes: ["source.clojure", "meta.expression.clojure", "meta.definition.global.clojure", "entity.global.clojure"]
102+
103+
it "tokenizes dynamic variables", ->
104+
mutables = ["*ns*", "*foo-bar*"]
105+
106+
for mutable in mutables
107+
{tokens} = grammar.tokenizeLine mutable
108+
expect(tokens[0]).toEqual value: mutable, scopes: ["source.clojure", "meta.symbol.dynamic.clojure"]
109+
110+
it "tokenizes metadata", ->
111+
{tokens} = grammar.tokenizeLine "^Foo"
112+
expect(tokens[0]).toEqual value: "^", scopes: ["source.clojure", "meta.metadata.simple.clojure"]
113+
expect(tokens[1]).toEqual value: "Foo", scopes: ["source.clojure", "meta.metadata.simple.clojure", "meta.symbol.clojure"]
114+
115+
{tokens} = grammar.tokenizeLine "^{:foo true}"
116+
expect(tokens[0]).toEqual value: "^{", scopes: ["source.clojure", "meta.metadata.map.clojure", "punctuation.section.metadata.map.begin.clojure"]
117+
expect(tokens[1]).toEqual value: ":foo", scopes: ["source.clojure", "meta.metadata.map.clojure", "constant.keyword.clojure"]
118+
expect(tokens[2]).toEqual value: " ", scopes: ["source.clojure", "meta.metadata.map.clojure"]
119+
expect(tokens[3]).toEqual value: "true", scopes: ["source.clojure", "meta.metadata.map.clojure", "constant.language.boolean.clojure"]
120+
expect(tokens[4]).toEqual value: "}", scopes: ["source.clojure", "meta.metadata.map.clojure", "punctuation.section.metadata.map.end.clojure"]
121+
122+
it "tokenizes functions", ->
123+
expressions = ["(foo)", "(foo 1 10)"]
124+
125+
for expr in expressions
126+
{tokens} = grammar.tokenizeLine expr
127+
expect(tokens[1]).toEqual value: "foo", scopes: ["source.clojure", "meta.expression.clojure", "entity.name.function.clojure"]
128+
129+
it "tokenizes vars", ->
130+
{tokens} = grammar.tokenizeLine "(func #'foo)"
131+
expect(tokens[2]).toEqual value: " #", scopes: ["source.clojure", "meta.expression.clojure"]
132+
expect(tokens[3]).toEqual value: "'foo", scopes: ["source.clojure", "meta.expression.clojure", "meta.var.clojure"]
133+
134+
it "tokenizes symbols", ->
135+
{tokens} = grammar.tokenizeLine "foo/bar"
136+
expect(tokens[0]).toEqual value: "foo", scopes: ["source.clojure", "meta.symbol.namespace.clojure"]
137+
expect(tokens[1]).toEqual value: "/", scopes: ["source.clojure"]
138+
expect(tokens[2]).toEqual value: "bar", scopes: ["source.clojure", "meta.symbol.clojure"]
139+
140+
it "tokenizes trailing whitespace", ->
141+
{tokens} = grammar.tokenizeLine " \n"
142+
expect(tokens[0]).toEqual value: " \n", scopes: ["source.clojure", "invalid.trailing-whitespace"]
143+
144+
testMetaSection = (metaScope, puncScope, startsWith, endsWith) ->
145+
# Entire expression on one line.
146+
{tokens} = grammar.tokenizeLine "#{startsWith}foo, bar#{endsWith}"
147+
148+
[start, mid..., end, after] = tokens
149+
150+
expect(start).toEqual value: startsWith, scopes: ["source.clojure", "meta.#{metaScope}.clojure", "punctuation.section.#{puncScope}.begin.clojure"]
151+
expect(end).toEqual value: endsWith, scopes: ["source.clojure", "meta.#{metaScope}.clojure", "punctuation.section.#{puncScope}.end.clojure"]
152+
153+
for token in mid
154+
expect(token.scopes.slice(0, 2)).toEqual ["source.clojure", "meta.#{metaScope}.clojure"]
155+
156+
# Expression broken over multiple lines.
157+
tokens = grammar.tokenizeLines("#{startsWith}foo\n bar#{endsWith}")
158+
159+
[start, mid..., after] = tokens[0]
160+
161+
expect(start).toEqual value: startsWith, scopes: ["source.clojure", "meta.#{metaScope}.clojure", "punctuation.section.#{puncScope}.begin.clojure"]
162+
163+
for token in mid
164+
expect(token.scopes.slice(0, 2)).toEqual ["source.clojure", "meta.#{metaScope}.clojure"]
165+
166+
[mid..., end, after] = tokens[1]
167+
168+
expect(end).toEqual value: endsWith, scopes: ["source.clojure", "meta.#{metaScope}.clojure", "punctuation.section.#{puncScope}.end.clojure"]
169+
170+
for token in mid
171+
expect(token.scopes.slice(0, 2)).toEqual ["source.clojure", "meta.#{metaScope}.clojure"]
172+
173+
it "tokenizes expressions", ->
174+
testMetaSection "expression", "expression", "(", ")"
175+
176+
it "tokenizes quoted expressions", ->
177+
testMetaSection "quoted-expression", "expression", "'(", ")"
178+
testMetaSection "quoted-expression", "expression", "`(", ")"
179+
180+
it "tokenizes vectors", ->
181+
testMetaSection "vector", "vector", "[", "]"
182+
183+
it "tokenizes maps", ->
184+
testMetaSection "map", "map", "{", "}"
185+
186+
it "tokenizes sets", ->
187+
testMetaSection "set", "set", "\#{", "}"
188+
15189
it "tokenizes functions in nested sexp", ->
16190
{tokens} = grammar.tokenizeLine "((foo bar) baz)"
17191
expect(tokens[0]).toEqual value: "(", scopes: ["source.clojure", "meta.expression.clojure", "punctuation.section.expression.begin.clojure"]

0 commit comments

Comments
 (0)