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
21- import Ide.Types (Config (.. ), OptLinkTo (.. ))
15+ import Ide.Types
2216import Test.Hls
2317import Test.Hls.FileSystem (copyDir )
24- import Text.Regex.TDFA ((=~) )
2518
2619tests :: TestTree
2720tests = let
@@ -35,64 +28,6 @@ tests = let
3528 check found targetRange
3629
3730
38-
39- checkHover :: (HasCallStack ) => Maybe Hover -> Session [Expect ] -> Session ()
40- checkHover hover expectations = traverse_ check =<< expectations where
41-
42- check :: (HasCallStack ) => Expect -> Session ()
43- check expected =
44- case hover of
45- Nothing -> unless (expected == ExpectNoHover ) $ liftIO $ assertFailure " no hover found"
46- Just Hover {_contents = (InL MarkupContent {_value = standardizeQuotes -> msg})
47- ,_range = rangeInHover } ->
48- case expected of
49- ExpectRange expectedRange -> checkHoverRange expectedRange rangeInHover msg
50- ExpectHoverRange expectedRange -> checkHoverRange expectedRange rangeInHover msg
51- ExpectHoverText snippets -> liftIO $ traverse_ (`assertFoundIn` msg) snippets
52- ExpectHoverExcludeText snippets -> liftIO $ traverse_ (`assertNotFoundIn` msg) snippets
53- ExpectHoverTextRegex re -> liftIO $ assertBool (" Regex not found in " <> T. unpack msg) (msg =~ re :: Bool )
54- ExpectNoHover -> liftIO $ assertFailure $ " Expected no hover but got " <> show hover
55- _ -> pure () -- all other expectations not relevant to hover
56- _ -> liftIO $ assertFailure $ " test not expecting this kind of hover info" <> show hover
57-
58- extractLineColFromHoverMsg :: T. Text -> [T. Text ]
59- extractLineColFromHoverMsg =
60- -- Hover messages contain multiple lines, and we are looking for the definition
61- -- site
62- T. lines
63- -- The line we are looking for looks like: "*Defined at /tmp/GotoHover.hs:22:3*"
64- -- So filter by the start of the line
65- >>> mapMaybe (T. stripPrefix " *Defined at" )
66- -- There can be multiple definitions per hover message!
67- -- See the test "field in record definition" for example.
68- -- The tests check against the last line that contains the above line.
69- >>> last
70- -- [" /tmp/", "22:3*"]
71- >>> T. splitOn (sourceFileName <> " :" )
72- -- "22:3*"
73- >>> last
74- -- ["22:3", ""]
75- >>> T. splitOn " *"
76- -- "22:3"
77- >>> head
78- -- ["22", "3"]
79- >>> T. splitOn " :"
80-
81- checkHoverRange :: Range -> Maybe Range -> T. Text -> Session ()
82- checkHoverRange expectedRange rangeInHover msg =
83- let
84- lineCol = extractLineColFromHoverMsg msg
85- -- looks like hovers use 1-based numbering while definitions use 0-based
86- -- turns out that they are stored 1-based in RealSrcLoc by GHC itself.
87- adjust Position {_line = l, _character = c} =
88- Position {_line = l + 1 , _character = c + 1 }
89- in
90- case map (read . T. unpack) lineCol of
91- [l,c] -> liftIO $ adjust (expectedRange ^. L. start) @=? Position l c
92- _ -> liftIO $ assertFailure $
93- " expected: " <> show (" [...]" <> sourceFileName <> " :<LINE>:<COL>**[...]" , Just expectedRange) <>
94- " \n but got: " <> show (msg, rangeInHover)
95-
9631 sourceFilePath = T. unpack sourceFileName
9732 sourceFileName = " GotoHover.hs"
9833
@@ -113,9 +48,9 @@ tests = let
11348 , tst (getTypeDefinitions, checkDefs) aL20 sourceFilePath (pure [ExpectNoDefinitions ]) " Polymorphic variable" ]
11449
11550 recordDotSyntaxTests =
116- [ tst (getHover, checkHover ) (Position 17 24 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" x :: MyRecord" ]]) " hover over parent"
117- , tst (getHover, checkHover ) (Position 17 25 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over dot shows child"
118- , tst (getHover, checkHover ) (Position 17 26 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over child"
51+ [ tst (getHover, checkHoverM ) (Position 17 24 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" x :: MyRecord" ]]) " hover over parent"
52+ , tst (getHover, checkHoverM ) (Position 17 25 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over dot shows child"
53+ , tst (getHover, checkHoverM ) (Position 17 26 ) (T. unpack " RecordDotSyntax.hs" ) (pure [ExpectHoverText [" _ :: MyChild" ]]) " hover over child"
11954 ]
12055
12156 test :: (HasCallStack ) => (TestTree -> a ) -> (TestTree -> b ) -> Position -> [Expect ] -> String -> (a , b )
@@ -131,7 +66,7 @@ tests = let
13166 ( runDef $ tst def look sourceFilePath expect title
13267 , runHover $ tst hover look sourceFilePath expect title ) where
13368 def = (getDefinitions, checkDefs)
134- hover = (getHover , checkHover )
69+ hover = (getHover , checkHoverM )
13570
13671 -- search locations expectations on results
13772 -- TODO: Lookup of record field should return exactly one result
0 commit comments