summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorw0rp <devw0rp@gmail.com>2020-09-06 22:37:37 +0100
committerw0rp <devw0rp@gmail.com>2020-09-06 22:37:37 +0100
commitc36053d4cc28fbc5fc0ee70ccb2c9a1b349eaaa3 (patch)
tree88d99ac08c11166e9849d869351374005f615465 /test
parent5bc49d204782617e01da65d83c0d9700a1b0a72f (diff)
downloadale-c36053d4cc28fbc5fc0ee70ccb2c9a1b349eaaa3.zip
Close #3268 - Implement :ALEImport
A new command, `:ALEImport`, has been added, which lets you import words at your cursor if a completion provider can provide a completion for that word which includes some additional text changes.
Diffstat (limited to 'test')
-rw-r--r--test/completion/test_ale_import_command.vader562
-rw-r--r--test/completion/test_completion_filtering.vader50
2 files changed, 595 insertions, 17 deletions
diff --git a/test/completion/test_ale_import_command.vader b/test/completion/test_ale_import_command.vader
new file mode 100644
index 00000000..2ba9b8d7
--- /dev/null
+++ b/test/completion/test_ale_import_command.vader
@@ -0,0 +1,562 @@
+Before:
+ Save g:ale_enabled
+ Save b:ale_enabled
+ Save g:ale_lint_on_text_changed
+ Save g:ale_completion_enabled
+ Save g:ale_completion_autoimport
+ Save g:ale_completion_max_suggestions
+ Save g:ale_linters
+ Save b:ale_linters
+
+ let g:ale_enabled = 0
+ let b:ale_enabled = 0
+ let g:ale_lint_on_text_changed = 'always'
+ let g:ale_completion_enabled = 0
+ let g:ale_completion_autoimport = 0
+ let g:ale_completion_max_suggestions = 50
+ let g:ale_linters = {'typescript': ['tsserver'], 'python': ['pyre']}
+ unlet! b:ale_linters
+
+ let g:server_started_value = 1
+ let g:request_id = 0
+ let g:LastCallback = v:null
+ let g:LastHandleCallback = v:null
+ let g:sent_message_list = []
+ let g:code_action_list = []
+ let g:execute_list = []
+ let g:ale_queue_call_list = []
+
+ runtime autoload/ale.vim
+ runtime autoload/ale/util.vim
+ runtime autoload/ale/code_action.vim
+ runtime autoload/ale/lsp.vim
+ runtime autoload/ale/lsp_linter.vim
+
+ function! ale#util#Execute(expr) abort
+ call add(g:execute_list, a:expr)
+ endfunction
+
+ function! ale#Queue(...) abort
+ call add(g:ale_queue_call_list, a:000)
+ endfunction
+
+ function! ale#lsp#RegisterCallback(id, Callback) abort
+ let g:LastHandleCallback = a:Callback
+ endfunction
+
+ function! ale#lsp#NotifyForChanges(id, buffer) abort
+ endfunction
+
+ function! ale#lsp#HasCapability(id, capability) abort
+ return 1
+ endfunction
+
+ function! ale#lsp#Send(id, message) abort
+ let g:request_id += 1
+
+ call add(g:sent_message_list, a:message)
+
+ return g:request_id
+ endfunction
+
+ function! ale#lsp_linter#StartLSP(buffer, linter, Callback) abort
+ let g:LastCallback = a:Callback
+
+ return g:server_started_value
+ endfunction
+
+ function! ale#code_action#HandleCodeAction(code_action, should_save) abort
+ Assert !a:should_save
+
+ call add(g:code_action_list, a:code_action)
+ endfunction
+
+ function GetLastMessage()
+ return get(g:execute_list, -1, '')
+ endfunction
+
+ function CheckLintStates(conn_id, message)
+ " Check that we request more linter results after adding completions.
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_enabled = 0
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_enabled = 1
+ let g:ale_lint_on_text_changed = 1
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 'normal'
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 'insert'
+
+ let g:ale_queue_call_list = []
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [[0, '']], g:ale_queue_call_list
+
+ let g:ale_queue_call_list = []
+ let g:ale_lint_on_text_changed = 'never'
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = '0'
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 0
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+
+ let g:ale_lint_on_text_changed = 'xxx'
+
+ call g:LastHandleCallback(a:conn_id, a:message)
+ AssertEqual [], g:ale_queue_call_list
+ endfunction
+
+After:
+ call ale#linter#Reset()
+
+ Restore
+
+ delfunction GetLastMessage
+ delfunction CheckLintStates
+
+ unlet! g:LastCallback
+ unlet! g:LastHandleCallback
+ unlet! g:request_id
+ unlet! g:server_started_value
+ unlet! g:sent_message_list
+ unlet! g:code_action_list
+ unlet! g:ale_queue_call_list
+ unlet! g:execute_list
+ unlet! g:received_message
+ unlet! b:ale_old_omnifunc
+ unlet! b:ale_old_completeopt
+ unlet! b:ale_completion_info
+ unlet! b:ale_completion_result
+ unlet! b:ale_complete_done_time
+
+ runtime autoload/ale.vim
+ runtime autoload/ale/util.vim
+ runtime autoload/ale/code_action.vim
+ runtime autoload/ale/lsp.vim
+ runtime autoload/ale/lsp_linter.vim
+
+Given typescript(Some example TypeScript code):
+ let xyz = 123
+ let foo = missingword
+
+ let abc = 456
+
+Execute(ALEImport should complain when there's no word at the cursor):
+ call setpos('.', [bufnr(''), 3, 1, 0])
+ ALEImport
+
+ AssertEqual 'echom ''Nothing to complete at cursor!''', GetLastMessage()
+
+Execute(ALEImport should tell the user if no LSP is available):
+ let g:server_started_value = 0
+
+ call setpos('.', [bufnr(''), 2, 16, 0])
+ ALEImport
+
+ AssertEqual
+ \ 'echom ''No completion providers are available.''',
+ \ GetLastMessage()
+
+Execute(ALEImport should request imports correctly for tsserver):
+ call setpos('.', [bufnr(''), 2, 16, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ call g:LastHandleCallback(347, {
+ \ 'request_seq': 1,
+ \ 'command': 'completions',
+ \ 'body': [
+ \ {'name': 'missingwordIgnoreMe'},
+ \ {'name': 'missingword'},
+ \ ],
+ \})
+
+ AssertEqual
+ \ [
+ \ [0, 'ts@completions', {
+ \ 'file': expand('%:p'),
+ \ 'includeExternalModuleExports': 1,
+ \ 'offset': 11,
+ \ 'line': 2,
+ \ 'prefix': 'missingword',
+ \ }],
+ \ [0, 'ts@completionEntryDetails', {
+ \ 'file': expand('%:p'),
+ \ 'entryNames': [{'name': 'missingword'}],
+ \ 'offset': 11,
+ \ 'line': 2,
+ \ }]
+ \ ],
+ \ g:sent_message_list
+ AssertEqual 2, b:ale_completion_info.request_id
+
+ let g:ale_enabled = 1
+ let g:received_message = {
+ \ 'request_seq': 2,
+ \ 'command': 'completionEntryDetails',
+ \ 'body': [
+ \ {
+ \ 'name': 'missingword',
+ \ 'kind': 'className',
+ \ 'displayParts': [],
+ \ 'codeActions': [{
+ \ 'description': 'import { missingword } from "./Something";',
+ \ 'changes': [],
+ \ }],
+ \ },
+ \ ],
+ \}
+ call g:LastHandleCallback(347, g:received_message)
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'import { missingword } from "./Something";',
+ \ 'changes': [],
+ \ },
+ \ ],
+ \ g:code_action_list
+
+ call CheckLintStates(347, g:received_message)
+
+Execute(ALEImport should tell the user when no completions were found from tsserver):
+ call setpos('.', [bufnr(''), 2, 16, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 11,
+ \ 'line': 2,
+ \ 'line_length': 21,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ call g:LastHandleCallback(347, {
+ \ 'request_seq': 1,
+ \ 'command': 'completions',
+ \ 'body': [
+ \ {'name': 'missingwordIgnoreMe'},
+ \ ],
+ \})
+
+ AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
+
+Given python(Some example Python code):
+ xyz = 123
+ foo = missingword
+
+ abc = 456
+
+Execute(ALEImport should request imports correctly for language servers):
+ call setpos('.', [bufnr(''), 2, 12, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ AssertEqual
+ \ [
+ \ [0, 'textDocument/completion', {
+ \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
+ \ 'position': {'character': 6, 'line': 1}
+ \ }],
+ \ ],
+ \ g:sent_message_list
+ AssertEqual 1, b:ale_completion_info.request_id
+
+ let g:ale_enabled = 1
+ let g:received_message = {
+ \ 'id': 1,
+ \ 'jsonrpc': '2.0',
+ \ 'result': {
+ \ 'isIncomplete': v:false,
+ \ 'items': [
+ \ {
+ \ 'detail': 'Some other word we should ignore',
+ \ 'filterText': 'missingwordIgnoreMe',
+ \ 'insertText': 'missingwordIgnoreMe',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingwordIgnoreMe',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something import missingwordIgnoreMe',
+ \ },
+ \ ],
+ \ },
+ \ {
+ \ 'detail': 'Some word without text edits',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ },
+ \ {
+ \ 'detail': 'The word we should use',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something import missingword',
+ \ },
+ \ ],
+ \ },
+ \ {
+ \ 'detail': 'The other word we should not use',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something_else import missingword',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \}
+ call g:LastHandleCallback(347, g:received_message)
+
+ AssertEqual
+ \ [
+ \ {
+ \ 'description': 'completion',
+ \ 'changes': [
+ \ {
+ \ 'fileName': expand('%:p'),
+ \ 'textChanges': [
+ \ {
+ \ 'start': {'line': 2, 'offset': 2},
+ \ 'end': {'line': 3, 'offset': 2},
+ \ 'newText': 'from something import missingword',
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ },
+ \ ],
+ \ g:code_action_list
+
+ call CheckLintStates(347, g:received_message)
+
+Execute(ALEImport should tell the user when no completions were found from a language server):
+ call setpos('.', [bufnr(''), 2, 12, 0])
+
+ ALEImport
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 0,
+ \ 'request_id': 0,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastCallback isnot v:null
+
+ call g:LastCallback(ale#linter#Get(&filetype)[0], {
+ \ 'connection_id': 347,
+ \ 'buffer': bufnr(''),
+ \})
+
+ AssertEqual
+ \ {
+ \ 'conn_id': 347,
+ \ 'request_id': 1,
+ \ 'source': 'ale-import',
+ \ 'column': 7,
+ \ 'line': 2,
+ \ 'line_length': 17,
+ \ 'prefix': 'missingword',
+ \ 'additional_edits_only': 1,
+ \ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
+ \ },
+ \ b:ale_completion_info
+ Assert g:LastHandleCallback isnot v:null
+
+ AssertEqual
+ \ [
+ \ [0, 'textDocument/completion', {
+ \ 'textDocument': {'uri': ale#path#ToURI(expand('%:p'))},
+ \ 'position': {'character': 6, 'line': 1}
+ \ }],
+ \ ],
+ \ g:sent_message_list
+ AssertEqual 1, b:ale_completion_info.request_id
+
+ let g:received_message = {
+ \ 'id': 1,
+ \ 'jsonrpc': '2.0',
+ \ 'result': {
+ \ 'isIncomplete': v:false,
+ \ 'items': [
+ \ {
+ \ 'detail': 'Some other word we should ignore',
+ \ 'filterText': 'missingwordIgnoreMe',
+ \ 'insertText': 'missingwordIgnoreMe',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingwordIgnoreMe',
+ \ 'sortText': '3ee19999missingword',
+ \ 'additionalTextEdits': [
+ \ {
+ \ 'range': {
+ \ 'start': {'line': 1, 'character': 1},
+ \ 'end': {'line': 2, 'character': 1},
+ \ },
+ \ 'newText': 'from something import missingwordIgnoreMe',
+ \ },
+ \ ],
+ \ },
+ \ {
+ \ 'detail': 'Some word without text edits',
+ \ 'filterText': 'missingword',
+ \ 'insertText': 'missingword',
+ \ 'insertTextFormat': 1,
+ \ 'kind': 6,
+ \ 'label': ' missingword',
+ \ 'sortText': '3ee19999missingword',
+ \ },
+ \ ],
+ \ },
+ \}
+ call g:LastHandleCallback(347, g:received_message)
+
+ AssertEqual 'echom ''No possible imports found.''', GetLastMessage()
diff --git a/test/completion/test_completion_filtering.vader b/test/completion/test_completion_filtering.vader
index c5f14266..172203a4 100644
--- a/test/completion/test_completion_filtering.vader
+++ b/test/completion/test_completion_filtering.vader
@@ -12,13 +12,24 @@ After:
Execute(Prefix filtering should work for Lists of strings):
AssertEqual
\ ['FooBar', 'foo'],
- \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo')
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 0)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
- \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.')
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 0)
AssertEqual
\ ['FooBar', 'FongBar', 'baz', 'foo'],
- \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '')
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '', 0)
+
+Execute(Exact filtering should work):
+ AssertEqual
+ \ ['foo'],
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], 'foo', 1)
+ AssertEqual
+ \ ['FooBar', 'FongBar', 'baz', 'foo'],
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'baz', 'foo'], '.', 1)
+ AssertEqual
+ \ ['Foo'],
+ \ ale#completion#Filter(bufnr(''), '', ['FooBar', 'FongBar', 'Foo', 'foo'], 'Foo', 1)
Execute(Prefix filtering should work for completion items):
AssertEqual
@@ -32,7 +43,8 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'baz'},
\ {'word': 'foo'},
\ ],
- \ 'foo'
+ \ 'foo',
+ \ 0,
\ )
AssertEqual
@@ -51,7 +63,8 @@ Execute(Prefix filtering should work for completion items):
\ {'word': 'baz'},
\ {'word': 'foo'},
\ ],
- \ '.'
+ \ '.',
+ \ 0,
\ )
Execute(Excluding words from completion results should work):
@@ -66,7 +79,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'Italian'},
\ {'word': 'it'},
\ ],
- \ 'it'
+ \ 'it',
+ \ 0,
\ )
AssertEqual
@@ -78,7 +92,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
- \ 'de'
+ \ 'de',
+ \ 0,
\ )
AssertEqual
@@ -90,7 +105,8 @@ Execute(Excluding words from completion results should work):
\ {'word': 'describe'},
\ {'word': 'Deutsch'},
\ ],
- \ '.'
+ \ '.',
+ \ 0,
\ )
Execute(Excluding words from completion results should work with lists of Strings):
@@ -98,29 +114,29 @@ Execute(Excluding words from completion results should work with lists of String
AssertEqual
\ ['Italian'],
- \ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it')
+ \ ale#completion#Filter(bufnr(''), '', ['Italian', 'it'], 'it', 0)
AssertEqual
\ ['Deutsch'],
- \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de')
+ \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], 'de', 0)
AssertEqual
\ ['Deutsch'],
- \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.')
+ \ ale#completion#Filter(bufnr(''), '', ['describe', 'Deutsch'], '.', 0)
AssertEqual
\ ['Deutsch'],
- \ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '')
+ \ ale#completion#Filter(bufnr(''), '', ['Deutsch'], '', 0)
Execute(Filtering shouldn't modify the original list):
let b:ale_completion_excluded_words = ['it', 'describe']
let b:suggestions = [{'word': 'describe'}]
- AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
+ AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
AssertEqual b:suggestions, [{'word': 'describe'}]
- AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de')
+ AssertEqual [], ale#completion#Filter(bufnr(''), '', b:suggestions, 'de', 0)
AssertEqual b:suggestions, [{'word': 'describe'}]
Execute(Filtering should respect filetype triggers):
let b:suggestions = [{'word': 'describe'}]
- AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.')
- AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.')
- AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::')
+ AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), '', b:suggestions, '.', 0)
+ AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '.', 0)
+ AssertEqual b:suggestions, ale#completion#Filter(bufnr(''), 'rust', b:suggestions, '::', 0)