@@ -20,6 +20,7 @@ import qualified Data.Text as Text
2020import Ide.Plugin.Cabal.LicenseSuggest (licenseErrorSuggestion )
2121import qualified Ide.Plugin.Cabal.Parse as Lib
2222import qualified Language.LSP.Protocol.Lens as L
23+ import qualified Language.LSP.Protocol.Types as LSP
2324import Outline (outlineTests )
2425import System.FilePath
2526import Test.Hls
@@ -36,6 +37,7 @@ main = do
3637 , contextTests
3738 , outlineTests
3839 , codeActionTests
40+ , gotoDefinitionTests
3941 ]
4042
4143-- ------------------------------------------------------------------------
@@ -227,3 +229,56 @@ codeActionTests = testGroup "Code Actions"
227229 InR action@ CodeAction {_title} <- codeActions
228230 guard (_title == " Replace with " <> license)
229231 pure action
232+
233+ -- ----------------------------------------------------------------------------
234+ -- Goto Definition Tests
235+ -- ----------------------------------------------------------------------------
236+
237+ gotoDefinitionTests :: TestTree
238+ gotoDefinitionTests = testGroup " Goto Definition"
239+ [ positiveTest " middle of identifier" (mkP 27 16 ) (mkR 6 0 7 22 )
240+ , positiveTest " left of identifier" (mkP 30 12 ) (mkR 10 0 17 40 )
241+ , positiveTest " right of identifier" (mkP 33 22 ) (mkR 20 0 23 34 )
242+ , positiveTest " left of '-' in identifier" (mkP 36 20 ) (mkR 6 0 7 22 )
243+ , positiveTest " right of '-' in identifier" (mkP 39 19 ) (mkR 10 0 17 40 )
244+ , positiveTest " identifier in identifier list" (mkP 42 16 ) (mkR 20 0 23 34 )
245+ , positiveTest " left of ',' right of identifier" (mkP 45 33 ) (mkR 10 0 17 40 )
246+ , positiveTest " right of ',' left of identifier" (mkP 48 34 ) (mkR 6 0 7 22 )
247+
248+ , negativeTest " right of ',' left of space" (mkP 51 23 )
249+ , negativeTest " right of ':' left of space" (mkP 54 11 )
250+ , negativeTest " not a definition" (mkP 57 8 )
251+ , negativeTest " empty space" (mkP 59 7 )
252+ ]
253+ where
254+ mkP :: UInt -> UInt -> Position
255+ mkP x1 y1 = Position x1 y1
256+
257+ mkR :: UInt -> UInt -> UInt -> UInt -> Range
258+ mkR x1 y1 x2 y2 = Range (mkP x1 y1) (mkP x2 y2)
259+
260+ getDefinition :: Show b => (Definition |? b ) -> Range
261+ getDefinition (InL (Definition (InL loc))) = loc^. L. range
262+ getDefinition unk = error $ " Unexpected pattern '" ++ show unk ++ " ' , expected '(InL (Definition (InL loc))'"
263+
264+ -- A positive tests checks if the provided range is equal
265+ -- to the expected range from the definition in the test file.
266+ -- The test emulates a goto-definition request of an actual definition.
267+ positiveTest :: TestName -> Position -> Range -> TestTree
268+ positiveTest testName cursorPos expectedRange =
269+ runCabalTestCaseSession testName " goto-definition" $ do
270+ doc <- openDoc " simple-with-common.cabal" " cabal"
271+ definitions <- getDefinitions doc cursorPos
272+ let locationRange = getDefinition definitions
273+ liftIO $ locationRange @?= expectedRange
274+
275+ -- A negative tests checks if the request failed and
276+ -- the provided result is empty, i.e. `InR $ InR Null`.
277+ -- The test emulates a goto-definition request of anything but an
278+ -- actual definition.
279+ negativeTest :: TestName -> Position -> TestTree
280+ negativeTest testName cursorPos =
281+ runCabalTestCaseSession testName " goto-definition" $ do
282+ doc <- openDoc " simple-with-common.cabal" " cabal"
283+ empty <- getDefinitions doc cursorPos
284+ liftIO $ empty @?= (InR $ InR LSP. Null )
0 commit comments