diff --git a/test/completion-test.fnl b/test/completion-test.fnl index 69528a5..ba6785f 100644 --- a/test/completion-test.fnl +++ b/test/completion-test.fnl @@ -3,9 +3,7 @@ (local {: view} (require :fennel)) (local {: ROOT-URI - : open-file - : completion-at - : setup-server} (require :test.utils)) + : create-client} (require :test.mock-client)) (local dispatch (require :fennel-ls.dispatch)) (local message (require :fennel-ls.message)) @@ -13,9 +11,9 @@ (local filename (.. ROOT-URI "/imaginary-file.fnl")) (fn check-completion [body line col expected ?unexpected] - (local self (doto [] setup-server)) - (open-file self filename body) - (let [response (dispatch.handle* self (completion-at filename line col)) + (let [client (doto (create-client) + (: :open-file! filename body)) + response (client:completion filename line col) seen (collect [_ suggestion (ipairs (. response 1 :result))] suggestion.label suggestion.label)] (if expected @@ -26,9 +24,9 @@ (is.nil (. seen exp) (.. exp " was suggested, but shouldn't be")))))) (fn check-no-completion [body line col expected ?unexpected] - (local self (doto [] setup-server)) - (open-file self filename body) - (let [response (dispatch.handle* self (completion-at filename line col))] + (let [client (doto (create-client) + (: :open-file! filename body)) + response (client:completion filename line col)] (is-matching (. response 1) {:jsonrpc "2.0" :id id :result nil} "there shouldn't be a result"))) diff --git a/test/diagnostic-test.fnl b/test/diagnostic-test.fnl index 507eb82..adb552d 100644 --- a/test/diagnostic-test.fnl +++ b/test/diagnostic-test.fnl @@ -3,8 +3,7 @@ (local {: view} (require :fennel)) (local {: ROOT-URI - : open-file - : setup-server} (require :test.utils)) + : create-client} (require :test.mock-client)) (local dispatch (require :fennel-ls.dispatch)) (local message (require :fennel-ls.message)) @@ -24,8 +23,8 @@ (describe "diagnostic messages" (it "handles compile errors" - (local self (doto [] setup-server)) - (let [responses (open-file self filename "(do do)") + (let [self (create-client) + responses (self:open-file! filename "(do do)") diagnostic (match responses [{:params {: diagnostics}}] @@ -38,8 +37,8 @@ (is diagnostic "expected a diagnostic"))) (it "handles parse errors" - (local self (doto [] setup-server)) - (let [responses (open-file self filename "(do (print :hello(]") + (let [self (create-client) + responses (self:open-file! filename "(do (print :hello(]") diagnostic (match responses [{:params {: diagnostics}}] @@ -52,8 +51,8 @@ (is diagnostic "expected a diagnostic"))) (it "handles (match)" - (local self (doto [] setup-server)) - (let [responses (open-file self filename "(match)")] + (let [self (create-client) + responses (self:open-file! filename "(match)")] (is-matching responses [{:params {:diagnostics @@ -62,8 +61,8 @@ "diagnostics should always have a range"))) (it "gives more than one error" - (local self (doto [] setup-server)) - (let [responses (open-file self filename "(unknown-global-1 unknown-global-2)")] + (let [self (create-client) + responses (self:open-file! filename "(unknown-global-1 unknown-global-2)")] (is-matching responses [{:params {:diagnostics [a b]}}] "there should be a diagnostic for each one here")))) diff --git a/test/goto-definition-test.fnl b/test/goto-definition-test.fnl index 2a166cc..b326070 100644 --- a/test/goto-definition-test.fnl +++ b/test/goto-definition-test.fnl @@ -3,7 +3,7 @@ (local is (require :test.is)) (local {: ROOT-URI - : setup-server} (require :test.utils)) + : create-client} (require :test.mock-client)) (local dispatch (require :fennel-ls.dispatch)) (local message (require :fennel-ls.message)) @@ -11,15 +11,12 @@ (describe "jump to definition" (fn check [request-file line char response-file start-line start-col end-line end-col] - (local self (doto [] setup-server)) - (let [message (dispatch.handle* self - (message.create-request 2 :textDocument/definition - {:position {:character char :line line} - :textDocument {:uri (.. ROOT-URI "/" request-file)}})) + (let [client (create-client) + message (client:definition (.. ROOT-URI :/ request-file) line char) uri (.. ROOT-URI "/" response-file)] (is-matching message - [{:jsonrpc "2.0" :id 2 + [{:jsonrpc "2.0" :id client.prev-id :result {: uri :range {:start {:line start-line :character start-col} :end {:line end-line :character end-col}}}}] diff --git a/test/hover-test.fnl b/test/hover-test.fnl index 37589cf..c6ac086 100644 --- a/test/hover-test.fnl +++ b/test/hover-test.fnl @@ -3,7 +3,7 @@ (local {: view} (require :fennel)) (local {: ROOT-URI - : setup-server} (require :test.utils)) + : create-client} (require :test.mock-client)) (local dispatch (require :fennel-ls.dispatch)) (local message (require :fennel-ls.message)) @@ -11,14 +11,11 @@ (describe "hover" (fn check [request-file line char response-string] - (local self (doto [] setup-server)) - (let [message (dispatch.handle* self - (message.create-request 2 "textDocument/hover" - {:position {:character char :line line} - :textDocument {:uri (.. ROOT-URI "/" request-file)}}))] + (let [self (create-client) + message (self:hover (.. ROOT-URI :/ request-file) line char)] (is-matching message - [{:jsonrpc "2.0" :id 2 + [{:jsonrpc "2.0" :id self.prev-id :result {:contents {:kind "markdown" @@ -50,12 +47,6 @@ (check "hover.fnl" 9 14 "```fnl\n{:field1 10 :field2 :colon-string}\n```")) (it "hovers over literally the very first character" - (local state (doto [] setup-server)) - (let [message (dispatch.handle* state - (message.create-request 2 "textDocument/hover" - {:position {:character 0 :line 0} - :textDocument {:uri (.. ROOT-URI "/hover.fnl")}}))] - (is-matching - message - [{:jsonrpc "2.0" :id 2}] - "")))) + (let [self (create-client) + message (self:hover (.. ROOT-URI "/hover.fnl") 0 0)] + (is-matching message [{:jsonrpc "2.0" :id 2}] "")))) diff --git a/test/init.fnl b/test/init.fnl index 637dd75..d37d954 100644 --- a/test/init.fnl +++ b/test/init.fnl @@ -4,8 +4,9 @@ (require :test.hover-test) (require :test.json-rpc-test) (require :test.misc-test) -(require :test.string-processing-test) +(require :test.references-test) (require :test.settings-test) +(require :test.string-processing-test) (let [{: passes : errors} (require :test.lust)] (print (.. passes " passes. " errors " errors.")) diff --git a/test/misc-test.fnl b/test/misc-test.fnl index 5c27364..2c71dff 100644 --- a/test/misc-test.fnl +++ b/test/misc-test.fnl @@ -2,10 +2,9 @@ (local is (require :test.is)) (local {: view &as fennel} (require :fennel)) -(local {: setup-server - : open-file +(local {: create-client : ROOT-URI} - (require :test.utils)) + (require :test.mock-client)) (local language (require :fennel-ls.language)) (local utils (require :fennel-ls.utils)) @@ -33,22 +32,22 @@ (describe "find-symbol" (it "finds a symbol and parents" - (local state (doto [] setup-server)) - (open-file state filename "(match [1 2 4] [1 2 sym-one] sym-one)") - (local file (. state.files filename)) - (local (symbol parents) (language.find-symbol file.ast 23)) - (is.equal symbol (fennel.sym :sym-one)) - (is-matching - ;; awful way to check AST equality, but I don't mind - parents [[1 2 [:sym-one]] [[:match] [1 2 4] [1 2 [:sym-one]] [:sym-one]]] - "bad parents")) + (let [state (doto (create-client) + (: :open-file! filename "(match [1 2 4] [1 2 sym-one] sym-one)")) + file (. state.server.files filename) + (symbol parents) (language.find-symbol file.ast 23)] + (is.equal symbol (fennel.sym :sym-one)) + (is-matching + ;; awful way to check AST equality, but I don't mind + parents [[1 2 [:sym-one]] [[:match] [1 2 4] [1 2 [:sym-one]] [:sym-one]]] + "bad parents"))) (it "finds nothing, but still gives parents" - (local state (doto [] setup-server)) - (open-file state filename "(match [1 2 4] [1 2 sym-one] sym-one)") - (local file (. state.files filename)) - (local (symbol parents) (language.find-symbol file.ast 18)) - (is.equal symbol nil) - (is-matching - parents [[1 2 [:sym-one]] [[:match] [1 2 4] [1 2 [:sym-one]] [:sym-one]]] - "bad parents"))) + (let [state (doto (create-client) + (: :open-file! filename "(match [1 2 4] [1 2 sym-one] sym-one)")) + file (. state.server.files filename) + (symbol parents) (language.find-symbol file.ast 18)] + (is.equal symbol nil) + (is-matching + parents [[1 2 [:sym-one]] [[:match] [1 2 4] [1 2 [:sym-one]] [:sym-one]]] + "bad parents")))) diff --git a/test/mock-client.fnl b/test/mock-client.fnl new file mode 100644 index 0000000..d5ffd0d --- /dev/null +++ b/test/mock-client.fnl @@ -0,0 +1,83 @@ +(local dispatch (require :fennel-ls.dispatch)) +(local message (require :fennel-ls.message)) + +(local ROOT-PATH + (-> (io.popen "pwd") + (: :read :*a) + (: :sub 1 -2) ;; take off newline + (.. "/test/test-project"))) +(local ROOT-URI + (.. "file://" ROOT-PATH)) + +(local initialization-message + {:id 1 + :jsonrpc "2.0" + :method "initialize" + :params + {:capabilities {} + :clientInfo {:name "Neovim" :version "0.7.2"} + :initializationOptions {} + :processId 16245 + :rootPath ROOT-PATH + :rootUri ROOT-URI + :trace "off" + :workspaceFolders [{:name ROOT-PATH + :uri ROOT-URI}]}}) + +(local mt {}) +(fn create-client [?config] + (let [self (doto {:server [] :prev-id 1} (setmetatable mt))] + (dispatch.handle* self.server initialization-message) + (if ?config + (dispatch.handle* self.server {:jsonrpc "2.0" + :method :workspace/didChangeConfiguration + :params ?config})) + self)) + +(fn next-id! [self] + (set self.prev-id (+ self.prev-id 1)) + self.prev-id) + +(fn open-file! [self name text] + (dispatch.handle* self.server + (message.create-notification :textDocument/didOpen + {:textDocument + {:uri name + :languageId "fennel" + :version 1 + : text}}))) + +(fn completion [self file line character] + (dispatch.handle* self.server + (message.create-request (next-id! self) :textDocument/completion + {:position {: line : character} + :textDocument {:uri file}}))) + +(fn definition [self file line character] + (dispatch.handle* self.server + (message.create-request (next-id! self) :textDocument/definition + {:position {: line : character} + :textDocument {:uri file}}))) + +(fn hover [self file line character] + (dispatch.handle* self.server + (message.create-request (next-id! self) :textDocument/hover + {:position {: line : character} + :textDocument {:uri file}}))) + +(fn references [self file line character ?includeDeclaration] + (dispatch.handle* self.server + (message.create-request (next-id! self) :textDocument/references + {:position {: line : character} + :textDocument {:uri file} + :context {:includeDeclaration ?includeDeclaration}}))) + +(set mt.__index + {: open-file! + : completion + : definition + : hover + : references}) + +{: create-client + : ROOT-URI} diff --git a/test/references-test.fnl b/test/references-test.fnl new file mode 100644 index 0000000..647b3ad --- /dev/null +++ b/test/references-test.fnl @@ -0,0 +1,18 @@ +(import-macros {: is-matching : describe : it : before-each} :test) +(local is (require :test.is)) + +(local {: view} (require :fennel)) +(local {: ROOT-URI + : create-client} (require :test.mock-client)) + +(local filename (.. ROOT-URI "/imaginary-file.fnl")) + +(fn check-references [body line col expected] + (let [client (doto (create-client) + (: :open-file! filename body)) + response (client:references filename line col)] + (is.same response []))) + +(describe "references") + ; (it "finds a reference from let" + ; (check-references "(let [x 10] x)" 0 1))) diff --git a/test/settings-test.fnl b/test/settings-test.fnl index f78c932..fb5cbc3 100644 --- a/test/settings-test.fnl +++ b/test/settings-test.fnl @@ -3,21 +3,17 @@ (local {: view} (require :fennel)) (local {: ROOT-URI - : open-file - : setup-server} (require :test.utils)) + : create-client} (require :test.mock-client)) (local dispatch (require :fennel-ls.dispatch)) (local message (require :fennel-ls.message)) (describe "settings" (it "can set the path" - (local self (doto [] (setup-server {:fennel-ls {:fennel-path "./?/?.fnl"}}))) - (open-file self (.. ROOT-URI :/test.fnl) "(local {: this-is-in-modname} (require :modname))") - (let [[{:result {:range message}}] - (dispatch.handle* self - (message.create-request 2 :textDocument/definition - {:position {:character 12 :line 0} - :textDocument {:uri (.. ROOT-URI :/test.fnl)}}))] + (let [client (doto (create-client {:fennel-ls {:fennel-path "./?/?.fnl"}}) + (: :open-file! (.. ROOT-URI :/test.fnl) "(local {: this-is-in-modname} (require :modname))")) + [{:result {:range message}}] + (client:definition (.. ROOT-URI :/test.fnl) 0 12)] (is.not.nil message) "body"))) diff --git a/test/utils.fnl b/test/utils.fnl deleted file mode 100644 index 9b30b68..0000000 --- a/test/utils.fnl +++ /dev/null @@ -1,50 +0,0 @@ -(local dispatch (require :fennel-ls.dispatch)) -(local message (require :fennel-ls.message)) - -(local ROOT-PATH - (-> (io.popen "pwd") - (: :read :*a) - (: :sub 1 -2) ;; take off newline - (.. "/test/test-project"))) -(local ROOT-URI - (.. "file://" ROOT-PATH)) - -(local initialization-message - {:id 1 - :jsonrpc "2.0" - :method "initialize" - :params - {:capabilities {} - :clientInfo {:name "Neovim" :version "0.7.2"} - :initializationOptions {} - :processId 16245 - :rootPath ROOT-PATH - :rootUri ROOT-URI - :trace "off" - :workspaceFolders [{:name ROOT-PATH - :uri ROOT-URI}]}}) - -(fn setup-server [self ?config] - (dispatch.handle* self initialization-message) - (if ?config - (dispatch.handle* self {:jsonrpc "2.0" - :method :workspace/didChangeConfiguration - :params ?config}))) - -(fn open-file [self name text] - (dispatch.handle* self - (message.create-notification :textDocument/didOpen - {:textDocument - {:uri name - :languageId "fennel" - :version 1 - : text}}))) - -(fn completion-at [file line character] - (message.create-request 2 :textDocument/completion - {:position {: line : character} :textDocument {:uri file}})) - -{: ROOT-URI - : setup-server - : open-file - : completion-at}