in tests, separate compile error diagnostics from lints
This commit is contained in:
parent
b5750b1a8a
commit
3bc530e11b
82
test/diagnostic.fnl
Normal file
82
test/diagnostic.fnl
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
(local faith (require :faith))
|
||||||
|
(local {: view} (require :fennel))
|
||||||
|
(local {: create-client-with-files} (require :test.utils))
|
||||||
|
|
||||||
|
(fn find [diagnostics e]
|
||||||
|
"returns the index of the diagnostic "
|
||||||
|
(accumulate [result nil
|
||||||
|
i d (ipairs diagnostics)
|
||||||
|
&until result]
|
||||||
|
(if (and (or (= e.message nil)
|
||||||
|
(if (= (type e.message) "function")
|
||||||
|
(e.message d.message)
|
||||||
|
(= e.message d.message)))
|
||||||
|
(or (= e.code nil)
|
||||||
|
(= e.code d.code))
|
||||||
|
(or (= e.range nil)
|
||||||
|
(and (= e.range.start.line d.range.start.line)
|
||||||
|
(= e.range.start.character d.range.start.character)
|
||||||
|
(= e.range.end.line d.range.end.line)
|
||||||
|
(= e.range.end.character d.range.end.character))))
|
||||||
|
i)))
|
||||||
|
|
||||||
|
(fn check [file-contents expected unexpected]
|
||||||
|
(let [{: diagnostics} (create-client-with-files file-contents)]
|
||||||
|
(each [_ e (ipairs unexpected)]
|
||||||
|
(let [i (find diagnostics e)]
|
||||||
|
(faith.= nil i (.. "Lint matching " (view e) "\n"
|
||||||
|
"from: " (view file-contents) "\n"
|
||||||
|
(view (. diagnostics i) {:escape-newlines? true})))))
|
||||||
|
|
||||||
|
(each [_ e (ipairs expected)]
|
||||||
|
(let [i (find diagnostics e)]
|
||||||
|
(faith.is i (.. "No lint matching " (view e) "\n"
|
||||||
|
"from: " (view file-contents) "\n"
|
||||||
|
(view diagnostics {:empty-as-sequence? true
|
||||||
|
:escape-newlines? true})))
|
||||||
|
(table.remove diagnostics i)))))
|
||||||
|
|
||||||
|
(fn test-compile-error []
|
||||||
|
(check "(do do)"
|
||||||
|
[{:message "tried to reference a special form without calling it"
|
||||||
|
:range {:start {:character 4 :line 0}
|
||||||
|
:end {:character 6 :line 0}}}] [])
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(fn test-parse-error []
|
||||||
|
(check "(do (print :hello(]"
|
||||||
|
[{:message "expected whitespace before opening delimiter ("
|
||||||
|
:range {:start {:character 17 :line 0}
|
||||||
|
:end {:character 17 :line 0}}}] [])
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(fn test-macro-error []
|
||||||
|
(check "(match)"
|
||||||
|
[{:range {:start {:character 0 :line 0}
|
||||||
|
:end {:character 7 :line 0}}}] [])
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(fn test-multiple-errors []
|
||||||
|
(check "(unknown-global-1 unknown-global-2)"
|
||||||
|
[{:message "unknown identifier: unknown-global-1"}
|
||||||
|
{:message "unknown identifier: unknown-global-2"}] [])
|
||||||
|
(check "(let [x unknown-global"
|
||||||
|
[{:message "unknown identifier: unknown-global"}
|
||||||
|
{:message "expected body expression"}
|
||||||
|
{:message "expected closing delimiters )]"}] [])
|
||||||
|
;; recovers from ()
|
||||||
|
(check "(let [x ()]
|
||||||
|
(print x +))"
|
||||||
|
[{:message "expected a function, macro, or special to call"}
|
||||||
|
{:message "tried to reference a special form without calling it"}] [])
|
||||||
|
;; recovers from mismatched let
|
||||||
|
(check "(let [x]
|
||||||
|
(print x +))"
|
||||||
|
[{:message "expected even number of name/value bindings"}
|
||||||
|
{:message "tried to reference a special form without calling it"}] [])
|
||||||
|
nil)
|
||||||
|
|
||||||
|
{: test-compile-error
|
||||||
|
: test-parse-error
|
||||||
|
: test-macro-error
|
||||||
|
: test-multiple-errors}
|
||||||
@ -16,6 +16,7 @@
|
|||||||
:test.string-processing
|
:test.string-processing
|
||||||
:test.capabilities
|
:test.capabilities
|
||||||
:test.settings
|
:test.settings
|
||||||
|
:test.diagnostic
|
||||||
:test.goto-definition
|
:test.goto-definition
|
||||||
:test.hover
|
:test.hover
|
||||||
:test.completion
|
:test.completion
|
||||||
|
|||||||
@ -36,44 +36,6 @@
|
|||||||
:escape-newlines? true})))
|
:escape-newlines? true})))
|
||||||
(table.remove diagnostics i)))))
|
(table.remove diagnostics i)))))
|
||||||
|
|
||||||
(fn test-compile-error []
|
|
||||||
(check "(do do)"
|
|
||||||
[{:message "tried to reference a special form without calling it"
|
|
||||||
:range {:start {:character 4 :line 0}
|
|
||||||
:end {:character 6 :line 0}}}] [])
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(fn test-parse-error []
|
|
||||||
(check "(do (print :hello(]"
|
|
||||||
[{:message "expected whitespace before opening delimiter ("
|
|
||||||
:range {:start {:character 17 :line 0}
|
|
||||||
:end {:character 17 :line 0}}}] [])
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(fn test-macro-error []
|
|
||||||
(check "(match)"
|
|
||||||
[{:range {:start {:character 0 :line 0}
|
|
||||||
:end {:character 7 :line 0}}}] [])
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(fn test-multiple-errors []
|
|
||||||
(check "(unknown-global-1 unknown-global-2)"
|
|
||||||
[{:message "unknown identifier: unknown-global-1"}
|
|
||||||
{:message "unknown identifier: unknown-global-2"}] [])
|
|
||||||
(check "(let [x unknown-global"
|
|
||||||
[{:message "unknown identifier: unknown-global"}
|
|
||||||
{:message "expected body expression"}
|
|
||||||
{:message "expected closing delimiters )]"}] [])
|
|
||||||
(check "(let [x ()]
|
|
||||||
(print +))"
|
|
||||||
[{:message "expected a function, macro, or special to call"}
|
|
||||||
{:message "tried to reference a special form without calling it"}] [])
|
|
||||||
(check "(let [x]
|
|
||||||
(print +))"
|
|
||||||
[{:message "expected even number of name/value bindings"}
|
|
||||||
{:message "tried to reference a special form without calling it"}] [])
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(fn test-unused []
|
(fn test-unused []
|
||||||
(check "(local x 10)"
|
(check "(local x 10)"
|
||||||
[{:message "unused definition: x"
|
[{:message "unused definition: x"
|
||||||
@ -94,6 +56,8 @@
|
|||||||
[{:code 301
|
[{:code 301
|
||||||
:range {:start {:character 5 :line 0}
|
:range {:start {:character 5 :line 0}
|
||||||
:end {:character 6 :line 0}}}] [])
|
:end {:character 6 :line 0}}}] [])
|
||||||
|
;; setting a field without reading is okay
|
||||||
|
(check "(fn [a b] (set a.x 10) (fn b.f []))" [] [{}])
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn test-ampersand []
|
(fn test-ampersand []
|
||||||
@ -114,11 +78,6 @@
|
|||||||
[] [{:message "unused definition: &"} {}])
|
[] [{:message "unused definition: &"} {}])
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(fn test-no-warnings []
|
|
||||||
;; setting a field without reading is okay
|
|
||||||
(check "(fn [a b] (set a.x 10) (fn b.f []))" [] [{}])
|
|
||||||
nil)
|
|
||||||
|
|
||||||
(fn test-unknown-module-field []
|
(fn test-unknown-module-field []
|
||||||
(check {:the-guy-they-tell-you-not-to-worry-about.fnl
|
(check {:the-guy-they-tell-you-not-to-worry-about.fnl
|
||||||
"(local M {:a 1})
|
"(local M {:a 1})
|
||||||
@ -208,13 +167,8 @@
|
|||||||
|
|
||||||
;; unused variable, when a function binding is only used in its body, and the function value is discarded
|
;; unused variable, when a function binding is only used in its body, and the function value is discarded
|
||||||
|
|
||||||
{: test-compile-error
|
{: test-unused
|
||||||
: test-parse-error
|
|
||||||
: test-macro-error
|
|
||||||
: test-multiple-errors
|
|
||||||
: test-unused
|
|
||||||
: test-ampersand
|
: test-ampersand
|
||||||
: test-no-warnings
|
|
||||||
: test-unknown-module-field
|
: test-unknown-module-field
|
||||||
: test-unnecessary-colon
|
: test-unnecessary-colon
|
||||||
: test-unset-var
|
: test-unset-var
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user