11{-# LANGUAGE ExplicitNamespaces #-}
22{-# LANGUAGE OverloadedStrings #-}
3- {-# LANGUAGE ViewPatterns #-}
43
54module FindDefinitionAndHoverTests (tests ) where
65
7- import Control.Monad
8- import Data.Foldable
6+ import Config
7+ import Control.Lens ( (^.) )
98import Data.Maybe
109import qualified Data.Text as T
10+ import Development.IDE.Test (expectDiagnostics )
11+ import Hover
1112import qualified Language.LSP.Protocol.Lens as L
1213import Language.LSP.Test
1314import System.Info.Extra (isWindows )
14-
15- import Config
16- import Control.Category ((>>>) )
17- import Control.Lens ((^.) )
18- import Development.IDE.Test (expectDiagnostics ,
19- standardizeQuotes )
20- import Hover
2115import Test.Hls
2216import Test.Hls.FileSystem (copyDir )
23- import Text.Regex.TDFA ((=~) )
2417
2518tests :: TestTree
2619tests = let
@@ -34,64 +27,6 @@ tests = let
3427 check found targetRange
3528
3629
37-
38- checkHover :: (HasCallStack ) => Maybe Hover -> Session [Expect ] -> Session ()
39- checkHover hover expectations = traverse_ check =<< expectations where
40-
41- check :: (HasCallStack ) => Expect -> Session ()
42- check expected =
43- case hover of
44- Nothing -> unless (expected == ExpectNoHover ) $ liftIO $ assertFailure " no hover found"
45- Just Hover {_contents = (InL MarkupContent {_value = standardizeQuotes -> msg})
46- ,_range = rangeInHover } ->
47- case expected of
48- ExpectRange expectedRange -> checkHoverRange expectedRange rangeInHover msg
49- ExpectHoverRange expectedRange -> checkHoverRange expectedRange rangeInHover msg
50- ExpectHoverText snippets -> liftIO $ traverse_ (`assertFoundIn` msg) snippets
51- ExpectHoverExcludeText snippets -> liftIO $ traverse_ (`assertNotFoundIn` msg) snippets
52- ExpectHoverTextRegex re -> liftIO $ assertBool (" Regex not found in " <> T. unpack msg) (msg =~ re :: Bool )
53- ExpectNoHover -> liftIO $ assertFailure $ " Expected no hover but got " <> show hover
54- _ -> pure () -- all other expectations not relevant to hover
55- _ -> liftIO $ assertFailure $ " test not expecting this kind of hover info" <> show hover
56-
57- extractLineColFromHoverMsg :: T. Text -> [T. Text ]
58- extractLineColFromHoverMsg =
59- -- Hover messages contain multiple lines, and we are looking for the definition
60- -- site
61- T. lines
62- -- The line we are looking for looks like: "*Defined at /tmp/GotoHover.hs:22:3*"
63- -- So filter by the start of the line
64- >>> mapMaybe (T. stripPrefix " *Defined at" )
65- -- There can be multiple definitions per hover message!
66- -- See the test "field in record definition" for example.
67- -- The tests check against the last line that contains the above line.
68- >>> last
69- -- [" /tmp/", "22:3*"]
70- >>> T. splitOn (sourceFileName <> " :" )
71- -- "22:3*"
72- >>> last
73- -- ["22:3", ""]
74- >>> T. splitOn " *"
75- -- "22:3"
76- >>> head
77- -- ["22", "3"]
78- >>> T. splitOn " :"
79-
80- checkHoverRange :: Range -> Maybe Range -> T. Text -> Session ()
81- checkHoverRange expectedRange rangeInHover msg =
82- let
83- lineCol = extractLineColFromHoverMsg msg
84- -- looks like hovers use 1-based numbering while definitions use 0-based
85- -- turns out that they are stored 1-based in RealSrcLoc by GHC itself.
86- adjust Position {_line = l, _character = c} =
87- Position {_line = l + 1 , _character = c + 1 }
88- in
89- case map (read . T. unpack) lineCol of
90- [l,c] -> liftIO $ adjust (expectedRange ^. L. start) @=? Position l c
91- _ -> liftIO $ assertFailure $
92- " expected: " <> show (" [...]" <> sourceFileName <> " :<LINE>:<COL>**[...]" , Just expectedRange) <>
93- " \n but got: " <> show (msg, rangeInHover)
94-
9530 sourceFilePath = T. unpack sourceFileName
9631 sourceFileName = " GotoHover.hs"
9732
@@ -110,9 +45,9 @@ tests = let
11045 , tst (getTypeDefinitions, checkDefs) aL20 sourceFilePath (pure [ExpectNoDefinitions ]) " Polymorphic variable" ]
11146
11247 recordDotSyntaxTests =
113- [ tst (getHover, checkHover ) (Position 17 24 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" x :: MyRecord" ]]) " hover over parent"
114- , tst (getHover, checkHover ) (Position 17 25 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over dot shows child"
115- , tst (getHover, checkHover ) (Position 17 26 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over child"
48+ [ tst (getHover, checkHoverM ) (Position 17 24 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" x :: MyRecord" ]]) " hover over parent"
49+ , tst (getHover, checkHoverM ) (Position 17 25 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over dot shows child"
50+ , tst (getHover, checkHoverM ) (Position 17 26 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over child"
11651 ]
11752
11853 test :: (HasCallStack ) => (TestTree -> a ) -> (TestTree -> b ) -> Position -> [Expect ] -> String -> (a , b )
@@ -128,7 +63,7 @@ tests = let
12863 ( runDef $ tst def look sourceFilePath expect title
12964 , runHover $ tst hover look sourceFilePath expect title ) where
13065 def = (getDefinitions, checkDefs)
131- hover = (getHover , checkHover )
66+ hover = (getHover , checkHoverM )
13267
13368 -- search locations expectations on results
13469 -- TODO: Lookup of record field should return exactly one result
0 commit comments