This commit is contained in:
Jeff Clement 2025-03-08 20:32:06 -07:00
parent 6471e799a8
commit 931e9d4aee
Signed by: jeff
GPG key ID: 3BCB43A3F0E1D7DA
93 changed files with 6881 additions and 8 deletions

View file

@ -0,0 +1,48 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Alias syntax' do
it 'colorize only module alias' do
str = "Enum.empty?(...)"
expect(str).to include_elixir_syntax('elixirAlias', 'Enum')
expect(str).to include_elixir_syntax('elixirOperator', '\.')
expect(str).to include_elixir_syntax('elixirId', 'empty?')
end
it 'colorize the module alias even if it starts with `!`' do
expect(<<~EOF).to include_elixir_syntax('elixirAlias', 'Enum')
!Enum.empty?(...)
EOF
end
it 'does not colorize the preceding ! in an alias' do
expect(<<~EOF).not_to include_elixir_syntax('elixirAlias', '!')
!Enum.empty?(...)
EOF
end
it 'does not colorize words starting with lowercase letters' do
expect(<<~EOF).not_to include_elixir_syntax('elixirAlias', 'aEnum')
aEnum.empty?(...)
EOF
end
it 'colorizes numbers in aliases' do
str = "S3Manager"
expect(str).to include_elixir_syntax('elixirAlias', 'S')
expect(str).to include_elixir_syntax('elixirAlias', '3')
expect(str).to include_elixir_syntax('elixirAlias', 'Manager')
end
it 'colorize dots in module alias' do
str = "Foo.Bar.Baz.fun(...)"
expect(str).to include_elixir_syntax('elixirAlias', 'Foo')
expect(str).to include_elixir_syntax('elixirAlias', '\.\(Bar\)\@=')
expect(str).to include_elixir_syntax('elixirAlias', 'Bar')
expect(str).to include_elixir_syntax('elixirAlias', '\.\(Baz\)\@=')
expect(str).to include_elixir_syntax('elixirAlias', 'Baz')
expect(str).to include_elixir_syntax('elixirOperator', '\.\(fun\)\@=')
expect(str).to include_elixir_syntax('elixirId', 'fun')
end
end

View file

@ -0,0 +1,32 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Anonymous function syntax' do
it 'anonymous function' do
expect(<<~'EOF').to include_elixir_syntax('elixirAnonymousFunction', 'fn')
fn(_, state) -> state end
EOF
end
it 'as a default argument' do
expect(<<~'EOF').to include_elixir_syntax('elixirAnonymousFunction', 'fn')
def exec(func \\ fn(_, state) -> state end) do
end
EOF
end
it 'as a default argument in a module' do
str = <<~'EOF'
defmodule HelloWorld do
def exec(func \\ fn(_, state) -> state end) do
end
end
EOF
expect(str).to include_elixir_syntax('elixirAnonymousFunction', 'fn')
# Test that the syntax properly closed
expect(str).to include_elixir_syntax('elixirBlockDefinition', '^end')
end
end

View file

@ -0,0 +1,91 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Atom syntax' do
KEYWORDS = %w(
def
defp
defmodule
defprotocol
defimpl
defrecord
defrecordp
defmacro
defmacrop
defdelegate
defoverridable
defexception
defcallback
defstruct
)
it '`atom:` style keyword used as an atom' do
KEYWORDS.each do |kw|
expect(<<~EOF).to include_elixir_syntax('elixirAtom', kw), "expected #{kw} to be an elixirAtom"
defmodule XmlElement do
require Record
import Record, only: [#{kw}: 2, extract: 2]
end
EOF
end
end
it '`:atom =>` style keyword used as an atom' do
KEYWORDS.each do |kw|
expect(<<~EOF).to include_elixir_syntax('elixirAtom', kw), "expected #{kw} to be an elixirAtom"
defmodule XmlElement do
require Record
import Record, only: [:#{kw} => 2, :extract => 2]
end
EOF
end
end
it 'atoms as part of a comprehension' do
s = 'for kvp <- map, do: &atomize_key/1, into: %{}'
expect(s).to include_elixir_syntax('elixirAtom', 'do')
expect(s).to include_elixir_syntax('elixirAtom', 'into')
end
it 'defoverridable' do
expect(<<~EOF).to include_elixir_syntax('elixirAtom', 'init:')
defmodule Test do
defmacro __using__(_options) do
quote do
def init(args) do
{:ok, args}
end
defoverridable init: 1
end
end
end
EOF
expect(<<~EOF).to include_elixir_syntax('elixirAtom', 'init:')
defmodule Test do
defmacro __using__(_options) do
quote do
def init(args) do
{:ok, args}
end
defoverridable [init: 1]
end
end
end
EOF
end
it '`Atom:` style atoms used in keyword list' do
expect(<<~EOF).to include_elixir_syntax('elixirAtom', 'Protocols:')
def project do
[
docs: [
groups_for_modules: [
Protocols: [Enumerable],
]
]
]
end
EOF
end
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Syntax case statements' do
it ':* is recognized as an atom' do
expect(<<~EOF).to include_elixir_syntax('elixirAtom', '\*')
case pattern do
:* -> :ok
_ -> :error
end
EOF
end
end

View file

@ -0,0 +1,32 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Comments syntax' do
it 'full line comment' do
expect(<<~EOF).to include_elixir_syntax('elixirComment', '#\ this\ is\ a\ comment')
# this is a comment
EOF
end
it 'end line comment' do
expect(<<~EOF).to include_elixir_syntax('elixirComment', '#\ this\ is\ a\ comment')
IO.puts "some text" # this is a comment
EOF
end
it 'after arguments' do
t = <<~EOF
def foo(<<
0 :: 1, # Foo
1 :: size(1), # Bar
# Blah
baz :: 8, # Baz
>>), do: baz
EOF
expect(t).to include_elixir_syntax('elixirComment', '#\ Foo')
expect(t).to include_elixir_syntax('elixirComment', '#\ Bar')
expect(t).to include_elixir_syntax('elixirComment', '#\ Blah')
expect(t).to include_elixir_syntax('elixirComment', '#\ Baz')
end
end

View file

@ -0,0 +1,30 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Defmodule syntax' do
it 'defines `defmodule` keyword as elixirModuleDefine' do
expect(<<~EOF).to include_elixir_syntax('elixirModuleDefine', 'defmodule')
defmodule HelloPhoenix.HelloController do
EOF
end
it 'defines module name as elixirModuleDeclaration' do
str = "defmodule HelloPhoenix.HelloController do"
expect(str).to include_elixir_syntax('elixirModuleDeclaration', 'HelloPhoenix')
expect(str).to include_elixir_syntax('elixirModuleDeclaration', '\.')
expect(str).to include_elixir_syntax('elixirModuleDeclaration', 'HelloController')
end
it 'does not define module name as elixirAlias' do
expect(<<~EOF).not_to include_elixir_syntax('elixirAlias', 'HelloPhoenix.HelloController')
defmodule HelloPhoenix.HelloController do
EOF
end
it 'defines `do` keyword as elixirBlock' do
expect(<<~EOF).to include_elixir_syntax('elixirBlock', 'do')
defmodule HelloPhoenix.HelloController do
EOF
end
end

View file

@ -0,0 +1,218 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'documentation syntax' do
describe 'string' do
it 'doc in double quotes' do
ex = '@doc "foo"'
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
expect(ex).to include_elixir_syntax('elixirDocStringDelimiter', '"')
end
it 'doc in sigil_S' do
ex = '@doc ~S(foo)'
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
expect(ex).to include_elixir_syntax('elixirDocSigilDelimiter', 'S')
end
end
describe 'heredoc' do
it 'doc with multiline content' do
ex = <<~'EOF'
@callbackdoc """
foo
"""
EOF
expect(ex).to include_elixir_syntax('elixirVariable', 'doc')
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
expect(ex).to include_elixir_syntax('elixirDocStringDelimiter', '"""')
end
it 'doc with sigil_S triple double-quoted multiline content' do
ex = <<~'EOF'
@doc ~S"""
foo
"""
EOF
expect(ex).to include_elixir_syntax('elixirVariable', 'doc')
expect(ex).to include_elixir_syntax('elixirDocSigilDelimiter', 'S"""')
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
end
it 'doc with sigil_S triple double-quoted multiline content with parentheses' do
ex = <<~'EOF'
@doc(~S"""
foo
""")
EOF
expect(ex).to include_elixir_syntax('elixirVariable', 'doc')
expect(ex).to include_elixir_syntax('elixirDocSigilDelimiter', 'S"""')
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
end
it 'doc with sigil_S triple single-quoted multiline content' do
ex = <<~'EOF'
@doc ~S'''
foo
'''
EOF
expect(ex).to include_elixir_syntax('elixirVariable', 'doc')
expect(ex).to include_elixir_syntax('elixirDocSigilDelimiter', "S'''")
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
end
it 'doc with sigil_S triple single-quoted multiline content with parentheses' do
ex = <<~'EOF'
@doc(~S'''
foo
''')
EOF
expect(ex).to include_elixir_syntax('elixirVariable', 'doc')
expect(ex).to include_elixir_syntax('elixirDocSigilDelimiter', "S'''")
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
end
it 'doc with triple single-quoted multiline content is not a doc string' do
ex = <<~'EOF'
@doc '''
foo
'''
EOF
expect(ex).not_to include_elixir_syntax('elixirDocString', 'foo')
end
it 'doc with multiline escaped' do
ex = <<~'EOF'
@doc """
foo
```
@xxx \"""
bar
\"""
```
baz
"""
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
expect(ex).to include_elixir_syntax('elixirDocString', 'bar')
expect(ex).to include_elixir_syntax('elixirDocString', 'baz')
end
it 'doc skip interpolation' do
ex = <<~'EOF'
@doc """
foo #{bar}
"""
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'foo')
expect(ex).to include_elixir_syntax('elixirDocStringDelimiter', '"""')
expect(ex).to include_elixir_syntax('elixirInterpolation', 'bar')
end
it 'doc with doctest' do
ex = <<~'EOF'
@doc """
doctest
iex> Enum.map [1, 2, 3], fn(x) ->
...> x * 2
...> end
[2, 4, 6]
"""
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'doctest')
expect(ex).to include_elixir_syntax('elixirDocTest', 'map')
expect(ex).to include_elixir_syntax('elixirDocTest', 'x \* 2')
expect(ex).to include_elixir_syntax('elixirDocTest', '2, 4, 6')
end
describe 'doctest without newline after' do
it 'with heredoc' do
ex = <<~'EOF'
@doc """
doctest
iex> 1 + 2
3
"""
def some_fun(x), do: x
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'doctest')
expect(ex).to include_elixir_syntax('elixirDocTest', '1 + 2')
expect(ex).to include_elixir_syntax('elixirDefine', 'def')
end
it 'with double quote' do
ex = <<~'EOF'
@doc "
doctest
iex> \"bob\"
\"bob\"
"
def some_fun(x), do: x
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'doctest')
expect(ex).to include_elixir_syntax('elixirDocTest', 'bob')
expect(ex).to include_elixir_syntax('elixirDefine', 'def')
end
it 'with sigil_S' do
ex = <<~'EOF'
@doc ~S(
doctest
iex> to_string("bob"\)
"bob"
)
def some_fun(x), do: x
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'doctest')
expect(ex).to include_elixir_syntax('elixirDocTest', 'bob')
expect(ex).to include_elixir_syntax('elixirDefine', 'def')
end
it 'with sigil_s' do
ex = <<~'EOF'
@doc ~s(
doctest
iex> to_string("bob"\)
"bob"
)
def some_fun(x), do: x
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'doctest')
expect(ex).to include_elixir_syntax('elixirDocTest', 'bob')
expect(ex).to include_elixir_syntax('elixirDefine', 'def')
end
end
it 'doc with inline code' do
ex = <<~'EOF'
@doc """
doctest with inline code `List.wrap([])`
"""
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'doctest')
expect(ex).to include_elixir_syntax('elixirDocString', 'wrap')
end
describe "use markdown for docs" do
before(:each) { VIM.command("let g:elixir_use_markdown_for_docs = 1") }
after(:each) { VIM.command("let g:elixir_use_markdown_for_docs = 0") }
it 'doc with inline code' do
ex = <<~'EOF'
@doc """
doc with inline code `List.wrap([])`
"""
EOF
expect(ex).to include_elixir_syntax('elixirDocString', 'inline')
expect(ex).to include_elixir_syntax('markdownCode', 'wrap')
end
end
end
end

View file

@ -0,0 +1,61 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Embedded Elixir syntax' do
it 'elixir' do
expect('<%= if true do %>').to include_eelixir_syntax('elixirKeyword', 'if')
expect('<%= if true do %>').to include_eelixir_syntax('elixirBoolean', 'true')
end
it 'expression' do
expect('<%= if true do %>').to include_eelixir_syntax('eelixirExpression', 'if')
expect('<% end %>').to include_eelixir_syntax('eelixirExpression', 'end')
end
it 'quote' do
expect('<%% def f %>').to include_eelixir_syntax('eelixirQuote', 'def')
end
it 'comment' do
expect('<%# foo bar baz %>').to include_eelixir_syntax('eelixirComment', 'foo')
end
it 'delimiters' do
expect('<% end %>').to include_eelixir_syntax('eelixirDelimiter', '<%')
expect('<% end %>').to include_eelixir_syntax('eelixirDelimiter', '%>')
end
end
describe 'Embedded Live Elixir syntax' do
it 'elixir' do
expect('<%= if true do %>').to include_leelixir_syntax('elixirKeyword', 'if')
expect('<%= if true do %>').to include_leelixir_syntax('elixirBoolean', 'true')
end
it 'expression' do
expect('<%= if true do %>').to include_leelixir_syntax('eelixirExpression', 'if')
expect('<% end %>').to include_leelixir_syntax('eelixirExpression', 'end')
end
it 'quote' do
expect('<%% def f %>').to include_leelixir_syntax('eelixirQuote', 'def')
end
it 'comment' do
expect('<%# foo bar baz %>').to include_leelixir_syntax('eelixirComment', 'foo')
end
it 'delimiters' do
expect('<% end %>').to include_leelixir_syntax('eelixirDelimiter', '<%')
expect('<% end %>').to include_leelixir_syntax('eelixirDelimiter', '%>')
end
end
describe 'Embedded Surface syntax' do
it 'elixir' do
expect('{{ @foo }}').to include_surface_syntax('elixirVariable', 'foo')
expect('{{ @foo }}').to include_surface_syntax('surfaceDelimiter', '{{')
expect('{{ @foo }}').to include_surface_syntax('surfaceDelimiter', '}}')
end
end

View file

@ -0,0 +1,174 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'ExUnit syntax' do
it 'test macro' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitMacro', 'test')
test 'that stuff works' do
assert true
end
EOF
end
it 'describe macro' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitMacro', 'describe')
describe 'some_function/1' do
test 'that stuff works' do
assert true
end
end
EOF
end
it 'setup macro' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitMacro', 'setup')
setup do
IO.puts "hi mom"
end
test 'that stuff works' do
assert true
end
EOF
end
it 'setup_all macro' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitMacro', 'setup_all')
setup_all do
IO.puts "hi mom"
end
test 'that stuff works' do
assert true
end
EOF
end
it 'on_exit macro' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitMacro', 'on_exit')
setup_all do
IO.puts "hi mom"
on_exit fn() ->
do_something
end
end
test 'that stuff works' do
assert true
end
EOF
end
it 'assert' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'assert')
test 'that stuff works' do
assert true
end
EOF
end
it 'assert_in_delta' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'assert_in_delta')
test 'that stuff works' do
assert_in_delta true
end
EOF
end
it 'assert_raise' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'assert_raise')
test 'that stuff works' do
assert_raise true
end
EOF
end
it 'assert_receive' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'assert_receive')
test 'that stuff works' do
assert_receive true
end
EOF
end
it 'assert_received' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'assert_received')
test 'that stuff works' do
assert_received true
end
EOF
end
it 'catch_error' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'catch_error')
test 'that stuff works' do
catch_error true
end
EOF
end
it 'catch_exit' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'catch_exit')
test 'that stuff works' do
catch_exit true
end
EOF
end
it 'catch_throw' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'catch_throw')
test 'that stuff works' do
catch_throw true
end
EOF
end
it 'flunk' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'flunk')
test 'that stuff works' do
flunk true
end
EOF
end
it 'refute' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'refute')
test 'that stuff works' do
refute true
end
EOF
end
it 'refute_in_delta' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'refute_in_delta')
test 'that stuff works' do
refute_in_delta true
end
EOF
end
it 'refute_receive' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'refute_receive')
test 'that stuff works' do
refute_receive true
end
EOF
end
it 'refute_received' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitAssert', 'refute_received')
test 'that stuff works' do
refute_received true
end
EOF
end
it 'doctest' do
expect(<<~EOF).to include_elixir_syntax('elixirExUnitMacro', 'doctest')
module MyTest do
doctest MyModule
end
EOF
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'function syntax' do
it 'doesnt treat underscored functions like unsued variables' do
expect(<<~EOF).to include_elixir_syntax('elixirId', '__ensure_defimpl__')
defp derive(protocol, for, struct, opts, env) do
# ... code ...
__ensure_defimpl__(protocol, for, env)
EOF
expect(<<~EOF).not_to include_elixir_syntax('elixirUnusedVariable', '__ensure_defimpl__')
defp derive(protocol, for, struct, opts, env) do
# ... code ...
__ensure_defimpl__(protocol, for, env)
EOF
end
end

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'defguard syntax' do
it 'defines `defguard` keyword as elixirGuard' do
expect(<<~EOF).to include_elixir_syntax('elixirGuard', 'defguard')
defguard some_guard(x) when is_integer(x)
EOF
end
it 'defines `defguardp` keyword as elixirPrivateGuard' do
expect(<<~EOF).to include_elixir_syntax('elixirPrivateGuard', 'defguardp')
defguardp some_private_guard(x) when is_integer(x)
EOF
end
end

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Kernel function syntax' do
it 'kernel function used as an atom key in a keyword list outside of a block' do
expect(<<~EOF).not_to include_elixir_syntax('elixirKeyword', 'length')
do
plug Plug.Parsers, length: 400_000_000
end
EOF
end
it 'kernel function used as an atom key in a keyword list contained in a block' do
expect(<<~EOF).not_to include_elixir_syntax('elixirKeyword', 'length')
plug Plug.Parsers, length: 400_000_000
EOF
end
end

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Keyword syntax' do
it 'for used as keyword' do
expect(<<~EOF).to include_elixir_syntax('elixirKeyword', 'for')
for v <- [1, 3, 3]
EOF
end
it 'case used as keyword' do
expect(<<~EOF).to include_elixir_syntax('elixirKeyword', 'case')
case true do
EOF
end
it 'raise used as keyword' do
expect(<<~EOF).to include_elixir_syntax('elixirKeyword', 'raise')
raise "oops"
EOF
expect(<<~EOF).to include_elixir_syntax('elixirKeyword', 'raise')
raise ArgumentError, message: "invalid argument foo"
EOF
end
end

View file

@ -0,0 +1,40 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'List syntax' do
it 'should properly handle "\\\\" inside' do
syntax = <<~EOF
'"\\\\'
var = 1
EOF
expect(syntax).to include_elixir_syntax('elixirId', 'var')
expect(syntax).not_to include_elixir_syntax('elixirString', 'var')
end
it 'recognizes lists' do
syntax = <<~EOF
[
:hello,
:world
]
EOF
expect(syntax).to include_elixir_syntax('elixirListDelimiter', '[')
expect(syntax).to include_elixir_syntax('elixirList', ':hello')
expect(syntax).to include_elixir_syntax('elixirListDelimiter', ']')
end
it 'recognizes lists inside functions' do
syntax = <<~EOF
def hello_world do
[
:hello,
:world
]
end
EOF
expect(syntax).to include_elixir_syntax('elixirListDelimiter', '[')
expect(syntax).to include_elixir_syntax('elixirList', ':hello')
expect(syntax).to include_elixir_syntax('elixirListDelimiter', ']')
end
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Map syntax' do
it 'maps' do
str = %q(%{name: "one"})
expect(str).to include_elixir_syntax('elixirMapDelimiter', '%')
expect(str).to include_elixir_syntax('elixirMapDelimiter', '{')
expect(str).to include_elixir_syntax('elixirAtom', 'name:')
expect(str).to include_elixir_syntax('elixirMap', 'name:')
expect(str).to include_elixir_syntax('elixirMapDelimiter', '}')
end
end

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Module function syntax' do
it 'for used as module function' do
expect(<<~EOF).to include_elixir_syntax('elixirId', 'for')
OverridesDefault.for
EOF
end
it 'case used as module function' do
expect(<<~EOF).to include_elixir_syntax('elixirId', 'case')
OverridesDefault.case
EOF
end
end

View file

@ -0,0 +1,45 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Numbers syntax' do
describe 'decimal' do
it 'positive is colorized' do
expect('123').to include_elixir_syntax('elixirNumber', '123')
end
it 'negative is colorized' do
expect('-123').to include_elixir_syntax('elixirNumber', '123')
end
end
describe 'hexadecimal' do
it 'positive is colorized' do
expect('0xdeadbeaf').to include_elixir_syntax('elixirNumber', '0xdeadbeaf')
end
it 'negative is colorized' do
expect('-0xdeadbeaf').to include_elixir_syntax('elixirNumber', '0xdeadbeaf')
end
end
describe 'octal' do
it 'positive is colorized' do
expect('0o777').to include_elixir_syntax('elixirNumber', '0o777')
end
it 'negative is colorized' do
expect('-0o777').to include_elixir_syntax('elixirNumber', '0o777')
end
end
describe 'binary' do
it 'positive is colorized' do
expect('0b1011').to include_elixir_syntax('elixirNumber', '0b1011')
end
it 'negative is colorized' do
expect('-0b1011').to include_elixir_syntax('elixirNumber', '0b1011')
end
end
end

View file

@ -0,0 +1,31 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Operators' do
it 'default argument' do
expect(<<~'EOF').to include_elixir_syntax('elixirOperator', '\\')
def foo(bar \\ :baz)
EOF
expect(<<~EOF).to include_elixir_syntax('elixirOperator', '\/')
def foo(bar // :baz)
EOF
end
it 'in' do
expect(<<~EOF).to include_elixir_syntax('elixirOperator', 'in')
'x' in ['x']
EOF
expect(<<~EOF).not_to include_elixir_syntax('elixirOperator', 'in')
:queue.in x, 5
EOF
end
it 'does not highlight operators inside of elixirIds' do
expect(<<~EOF).not_to include_elixir_syntax('elixirOperator', 'in')
incoming
EOF
end
end

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
# encoding: utf-8
require 'spec_helper'
describe 'Record syntax' do
it 'private record symbol' do
expect(<<~EOF).to include_elixir_syntax('elixirAtom', ':user')
defrecordp :user, name: "José", age: 25
EOF
end
end

View file

@ -0,0 +1,146 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Sigil syntax' do
it 'as function argument' do
expect('def f(~s(")), do: true').to include_elixir_syntax('elixirSigilDelimiter', '\~s(')
expect('def f(~s(")), do: true').to include_elixir_syntax('elixirSigil', '"')
expect("def f(~s(')), do: true").to include_elixir_syntax('elixirSigil', "'")
expect('def f(~s(")), do: true').not_to include_elixir_syntax('elixirSigilDelimiter', '"')
end
it 'as function argument multiline content' do
ex = <<~'EOF'
f(
~S"""
foo
""",
bar
)
EOF
expect(ex).to include_elixir_syntax('elixirSigilDelimiter', 'S"""')
expect(ex).to include_elixir_syntax('elixirSigil', 'foo')
end
describe 'upper case' do
it 'string' do
expect('~S(string)').to include_elixir_syntax('elixirSigilDelimiter', 'S')
expect('~S(string)').to include_elixir_syntax('elixirSigil', 'string')
end
it 'character list' do
expect('~C(charlist)').to include_elixir_syntax('elixirSigilDelimiter', 'C')
expect('~C(charlist)').to include_elixir_syntax('elixirSigil', 'charlist')
end
it 'regular expression' do
expect('~R(regex)').to include_elixir_syntax('elixirSigilDelimiter', 'R')
expect('~R(regex)').to include_elixir_syntax('elixirSigil', 'regex')
end
it 'list of words' do
expect('~W(list of words)').to include_elixir_syntax('elixirSigilDelimiter', 'W')
expect('~W(list of words)').to include_elixir_syntax('elixirSigil', 'list')
end
it 'delimited with parenthesis' do
expect('~S(foo bar)').to include_elixir_syntax('elixirSigilDelimiter', '(')
expect('~S(foo bar)').to include_elixir_syntax('elixirSigilDelimiter', ')')
end
it 'delimited with braces' do
expect('~S{foo bar}').to include_elixir_syntax('elixirSigilDelimiter', '{')
expect('~S{foo bar}').to include_elixir_syntax('elixirSigilDelimiter', '}')
end
it 'delimited with brackets' do
expect('~S[foo bar]').to include_elixir_syntax('elixirSigilDelimiter', '[')
expect('~S[foo bar]').to include_elixir_syntax('elixirSigilDelimiter', ']')
end
it 'escapes double quotes unless only preceded by whitespace' do
expect(<<~EOF).to include_elixir_syntax('elixirSigilDelimiter', %q(^\s*\zs"""))
~r"""
foo """
"""
EOF
end
it 'escapes single quotes unless only preceded by whitespace' do
expect(<<~EOF).to include_elixir_syntax('elixirSigilDelimiter', %q(^\s*\zs'''))
~r'''
foo '''
'''
EOF
end
it 'without escapes' do
expect('~S(foo \n bar)').not_to include_elixir_syntax('elixirRegexEscape', '\\')
end
it 'without interpolation' do
expect('~S(foo #{bar})').not_to include_elixir_syntax('elixirInterpolation', 'bar')
end
it 'without escaped parenthesis' do
expect('~S(\( )').not_to include_elixir_syntax('elixirRegexEscapePunctuation', '( ')
end
it 'Live EEx' do
expect('~L"""liveview template"""').to include_elixir_syntax('elixirSigilDelimiter', '"""')
end
it 'Surface EEx' do
expect('~H"""surface template"""').to include_elixir_syntax('elixirSigilDelimiter', '"""')
end
it 'EEx' do
expect('~E"""Phoenix.HTML template"""').to include_elixir_syntax('elixirSigilDelimiter', '"""')
expect('~e"""Phoenix.HTML template"""').to include_elixir_syntax('elixirSigilDelimiter', '"""')
end
end
describe 'lower case' do
it 'string' do
expect('~s(string)').to include_elixir_syntax('elixirSigilDelimiter', 's')
expect('~s(string)').to include_elixir_syntax('elixirSigil', 'string')
end
it 'character list' do
expect('~c(charlist)').to include_elixir_syntax('elixirSigilDelimiter', 'c')
expect('~c(charlist)').to include_elixir_syntax('elixirSigil', 'charlist')
end
it 'regular expression' do
expect('~r(regex)').to include_elixir_syntax('elixirSigilDelimiter', 'r')
expect('~r(regex)').to include_elixir_syntax('elixirSigil', 'regex')
end
it 'list of words' do
expect('~w(list of words)').to include_elixir_syntax('elixirSigilDelimiter', 'w')
expect('~w(list of words)').to include_elixir_syntax('elixirSigil', 'list')
end
it 'with escapes' do
expect('~s(foo \n bar)').to include_elixir_syntax('elixirRegexEscapePunctuation', '\\')
end
it 'with interpolation' do
expect('~s(foo #{bar})').to include_elixir_syntax('elixirInterpolation', 'bar')
end
it 'with escaped parenthesis' do
expect('~s(\( )').to include_elixir_syntax('elixirRegexEscapePunctuation', '( ')
end
it 'interpolation with slashes' do
expect('~s/foo #{bar}/').to include_elixir_syntax('elixirInterpolation', 'bar')
end
it 'escapes with slashes' do
expect('~s/foo \n bar/').to include_elixir_syntax('elixirRegexEscapePunctuation', '\\')
end
end
end

View file

@ -0,0 +1,109 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'String syntax' do
describe 'binary' do
it 'double quoted string' do
expect('foo "test"').to include_elixir_syntax('elixirString', 'test')
end
it 'double quoted string with escaped quote' do
expect('"this \"test is all one string"').to include_elixir_syntax('elixirString', 'test')
end
it 'charlist with escaped quote' do
expect(<<-'EOF').to include_elixir_syntax('elixirCharList', 'test')
'this \'test is all one charlist'
EOF
end
it 'interpolation in string' do
expect('do_something "foo #{test}"').to include_elixir_syntax('elixirInterpolation', 'test')
end
end
describe 'heredoc' do
it 'heredoc must be string' do
ex = <<~EOF
def function do
"""
foo "test"
"""
end
EOF
expect(ex).to include_elixir_syntax('elixirString', 'foo')
expect(ex).to include_elixir_syntax('elixirString', 'test')
end
it 'interpolation in string in heredoc' do
expect(<<~'EOF').to include_elixir_syntax('elixirInterpolation', '#{')
def function do
"""
foo "#{test}"
"""
end
EOF
end
it 'interpolation in heredoc' do
expect(<<~'EOF').to include_elixir_syntax('elixirInterpolation', '#{')
def function do
"""
foo #{test}
"""
end
EOF
end
it 'correctly terminates heredocs with no spaces at the start of the line' do
expect(<<~'EOF'.gsub(/^\s+/, '')).to include_elixir_syntax('elixirAtom', ':bar')
"""
foo
"""
:bar
EOF
expect(<<~'EOF'.gsub(/^\s+/, '')).to include_elixir_syntax('elixirAtom', ':bar')
'''
foo
'''
:bar
EOF
end
it 'interpolation with a tuple' do
str = <<~'EOF'
"Failed sending tasks #{inspect {:unexpected_status_code, s}}"
EOF
expect(str).not_to include_elixir_syntax('elixirInterpolationDelimiter', '}}"$')
expect(str).to include_elixir_syntax('elixirInterpolationDelimiter', '}"$')
end
it 'interpolation with a tuple' do
str = <<~'EOF'
"Failed sending tasks #{inspect %{unexpected_status_code: s}}"
EOF
expect(str).not_to include_elixir_syntax('elixirInterpolationDelimiter', '}}"$')
expect(str).to include_elixir_syntax('elixirInterpolationDelimiter', '}"$')
end
it 'interpolation with a struct' do
str = <<~'EOF'
"Failed sending tasks #{inspect %ResponseStruct{unexpected_status_code: s}}"
EOF
expect(str).not_to include_elixir_syntax('elixirInterpolationDelimiter', '}}"$')
expect(str).to include_elixir_syntax('elixirInterpolationDelimiter', '}"$')
end
it 'strings with embedded braces' do
str = <<~EOF
x = [
{:text, "asd {"},
{:text, "qwe"},
]
EOF
expect(str).to include_elixir_syntax('elixirString', '{"}')
end
end
end

View file

@ -0,0 +1,64 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Struct syntax' do
it 'without defaults' do
expect(<<~EOF).to include_elixir_syntax('elixirAtom', ':name')
defstruct [:name, :age]
EOF
end
it 'with defaults' do
expect(<<~EOF).to include_elixir_syntax('elixirAtom', 'name:')
defstruct name: "john", age: 27
EOF
end
it 'structs' do
str = %q(%MyStruct{name: "one"})
expect(str).to include_elixir_syntax('elixirStructDelimiter', '%')
expect(str).to include_elixir_syntax('elixirStruct', '%')
expect(str).to include_elixir_syntax('elixirAlias', 'MyStruct')
expect(str).to include_elixir_syntax('elixirStruct', 'MyStruct')
expect(str).to include_elixir_syntax('elixirStructDelimiter', '{')
expect(str).to include_elixir_syntax('elixirStruct', '{')
expect(str).to include_elixir_syntax('elixirAtom', 'name:')
expect(str).to include_elixir_syntax('elixirStruct', 'name:')
expect(str).to include_elixir_syntax('elixirStructDelimiter', '}')
end
it 'properly closes strings in structs' do
str = <<~'EOF'
%MyStruct{url: "http://127.0.0.1:#{port}"} # anchor
# this should not be a string still
EOF
expect(str).to include_elixir_syntax('elixirStruct', '{url')
expect(str).to include_elixir_syntax('elixirStringDelimiter', '"http')
expect(str).to include_elixir_syntax('elixirStruct', '"http')
expect(str).to include_elixir_syntax('elixirInterpolationDelimiter', '#{')
expect(str).to include_elixir_syntax('elixirStruct', '#{')
expect(str).to include_elixir_syntax('elixirInterpolationDelimiter', '}"}')
expect(str).to include_elixir_syntax('elixirStruct', '}"}')
expect(str).not_to include_elixir_syntax('elixirStructDelimiter', '}"}')
expect(str).to include_elixir_syntax('elixirStringDelimiter', '"}')
expect(str).to include_elixir_syntax('elixirStruct', '"}')
expect(str).to include_elixir_syntax('elixirStringDelimiter', '"}')
expect(str).to include_elixir_syntax('elixirStruct', '"}')
expect(str).to include_elixir_syntax('elixirStructDelimiter', '} #')
expect(str).to include_elixir_syntax('elixirComment', '# this should not be a string still')
end
end

View file

@ -0,0 +1,17 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Tuple syntax' do
it 'tuples' do
str = %q({:name, "one"})
expect(str).to include_elixir_syntax('elixirTupleDelimiter', '{')
expect(str).to include_elixir_syntax('elixirTuple', '{')
expect(str).to include_elixir_syntax('elixirAtom', ':name')
expect(str).to include_elixir_syntax('elixirTuple', ':name')
expect(str).to include_elixir_syntax('elixirTupleDelimiter', '}')
end
end

View file

@ -0,0 +1,75 @@
# frozen_string_literal: true
require 'spec_helper'
describe 'Variable syntax' do
it 'unused' do
expect(<<~EOF).to include_elixir_syntax('elixirUnusedVariable', '_from')
def handle_call(:pop, _from, [h|stack]) do
{ :reply, h, stack }
end
EOF
end
it 'unused in function body' do
expect(<<~EOF).not_to include_elixir_syntax('elixirUnusedVariable', '_from')
def handle_call(:pop)
Hello._from
end
EOF
end
it 'unused, multiple lines' do
expect(<<~EOF).to include_elixir_syntax('elixirUnusedVariable', '_from')
def handle_call(:pop,
_from,
[h|stack]) do
{ :reply, h, stack }
end
EOF
end
it 'unused, single char' do
expect(<<~EOF).to include_elixir_syntax('elixirUnusedVariable', '_')
def call(:pop, _, [h|stack]) do
{ :reply, h, stack }
end
EOF
end
it 'unused in pattern_match' do
str = <<~EOF
def sign_in(conn, %{
"data" => %{
"type" => "doctor",
"attributes" => %{
"institution_code" => institution_code,
"password" => password,
"email_or_phone" => email_or_phone}}}, _user, _claims) do
:ok
end
EOF
expect(str).to include_elixir_syntax('elixirUnusedVariable', '_user')
expect(str).to include_elixir_syntax('elixirUnusedVariable', '_claims')
end
it 'unused, in anonymous function, inline' do
expect(<<~EOF).to include_elixir_syntax('elixirUnusedVariable', '_unused')
fun = fn _unused -> false end
EOF
end
it 'unused, in anonymous function, multiple lines' do
expect(<<~EOF).to include_elixir_syntax('elixirUnusedVariable', '_unused')
fun = fn
([], _unused) -> true
end
EOF
end
it 'unused, in pattern matching' do
expect(<<~EOF).to include_elixir_syntax('elixirUnusedVariable', '_unused')
_unused = false
EOF
end
end