@@ -124,6 +124,7 @@ import Ide.PluginUtils (pluginDescToIdePlugin
124
124
import Ide.Types
125
125
import qualified Language.LSP.Types as LSP
126
126
import qualified Language.LSP.Types.Lens as L
127
+ import Language.LSP.Types.Lens (workspace , didChangeWatchedFiles )
127
128
import qualified Progress
128
129
import System.Time.Extra
129
130
import Test.Tasty
@@ -133,7 +134,6 @@ import Test.Tasty.Ingredients.Rerun
133
134
import Test.Tasty.QuickCheck
134
135
import Text.Printf (printf )
135
136
import Text.Regex.TDFA ((=~) )
136
- import Language.LSP.Types.Lens (workspace , didChangeWatchedFiles )
137
137
138
138
data Log
139
139
= LogGhcIde Ghcide. Log
@@ -4615,6 +4615,7 @@ completionTests
4615
4615
, testGroup " package" packageCompletionTests
4616
4616
, testGroup " project" projectCompletionTests
4617
4617
, testGroup " other" otherCompletionTests
4618
+ , testGroup " doc" completionDocTests
4618
4619
]
4619
4620
4620
4621
completionTest :: String -> [T. Text ] -> Position -> [(T. Text , CompletionItemKind , T. Text , Bool , Bool , Maybe (List TextEdit ))] -> TestTree
@@ -5067,7 +5068,7 @@ packageCompletionTests =
5067
5068
_ <- waitForDiagnostics
5068
5069
compls <- getCompletions doc (Position 2 12 )
5069
5070
let compls' =
5070
- [T. drop 1 $ T. dropEnd 10 d
5071
+ [T. drop 1 $ T. dropEnd 3 d
5071
5072
| CompletionItem {_documentation = Just (CompletionDocMarkup (MarkupContent MkMarkdown d)), _label}
5072
5073
<- compls
5073
5074
, _label == " fromList"
@@ -5087,7 +5088,7 @@ packageCompletionTests =
5087
5088
_ <- waitForDiagnostics
5088
5089
compls <- getCompletions doc (Position 2 7 )
5089
5090
let compls' =
5090
- [T. drop 1 $ T. dropEnd 10 d
5091
+ [T. drop 1 $ T. dropEnd 3 d
5091
5092
| CompletionItem {_documentation = Just (CompletionDocMarkup (MarkupContent MkMarkdown d)), _label}
5092
5093
<- compls
5093
5094
, _label == " Map"
@@ -5171,7 +5172,7 @@ projectCompletionTests =
5171
5172
]
5172
5173
compls <- getCompletions doc (Position 1 10 )
5173
5174
let compls' =
5174
- [T. drop 1 $ T. dropEnd 10 d
5175
+ [T. drop 1 $ T. dropEnd 3 d
5175
5176
| CompletionItem {_documentation = Just (CompletionDocMarkup (MarkupContent MkMarkdown d)), _label}
5176
5177
<- compls
5177
5178
, _label == " anidentifier"
@@ -5230,6 +5231,97 @@ projectCompletionTests =
5230
5231
item ^. L. label @?= " anidentifier"
5231
5232
]
5232
5233
5234
+ completionDocTests :: [TestTree ]
5235
+ completionDocTests =
5236
+ [ testSession " local define" $ do
5237
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5238
+ [ " module A where"
5239
+ , " foo = ()"
5240
+ , " bar = fo"
5241
+ ]
5242
+ let expected = " *Defined at line 2, column 1 in this module*\n "
5243
+ test doc (Position 2 8 ) " foo" Nothing [expected]
5244
+ , testSession " local empty doc" $ do
5245
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5246
+ [ " module A where"
5247
+ , " foo = ()"
5248
+ , " bar = fo"
5249
+ ]
5250
+ test doc (Position 2 8 ) " foo" Nothing [" *Defined at line 2, column 1 in this module*\n " ]
5251
+ , brokenForGhc9 $ testSession " local single line doc without '\\ n'" $ do
5252
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5253
+ [ " module A where"
5254
+ , " -- |docdoc"
5255
+ , " foo = ()"
5256
+ , " bar = fo"
5257
+ ]
5258
+ test doc (Position 3 8 ) " foo" Nothing [" *Defined at line 3, column 1 in this module*\n * * *\n docdoc\n " ]
5259
+ , brokenForGhc9 $ testSession " local multi line doc with '\\ n'" $ do
5260
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5261
+ [ " module A where"
5262
+ , " -- | abcabc"
5263
+ , " --"
5264
+ , " foo = ()"
5265
+ , " bar = fo"
5266
+ ]
5267
+ test doc (Position 4 8 ) " foo" Nothing [" *Defined at line 4, column 1 in this module*\n * * *\n abcabc\n " ]
5268
+ , brokenForGhc9 $ testSession " local multi line doc without '\\ n'" $ do
5269
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5270
+ [ " module A where"
5271
+ , " -- | abcabc"
5272
+ , " --"
5273
+ , " --def"
5274
+ , " foo = ()"
5275
+ , " bar = fo"
5276
+ ]
5277
+ test doc (Position 5 8 ) " foo" Nothing [" *Defined at line 5, column 1 in this module*\n * * *\n abcabc\n\n def\n " ]
5278
+ , testSession " extern empty doc" $ do
5279
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5280
+ [ " module A where"
5281
+ , " foo = od"
5282
+ ]
5283
+ let expected = " *Imported from 'Prelude'*\n "
5284
+ test doc (Position 1 8 ) " odd" (Just $ T. length expected) [expected]
5285
+ , brokenForMacGhc9 $ brokenForWinGhc9 $ testSession " extern single line doc without '\\ n'" $ do
5286
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5287
+ [ " module A where"
5288
+ , " foo = no"
5289
+ ]
5290
+ let expected = " *Imported from 'Prelude'*\n * * *\n\n\n Boolean \" not\"\n "
5291
+ test doc (Position 1 8 ) " not" (Just $ T. length expected) [expected]
5292
+ , brokenForMacGhc9 $ brokenForWinGhc9 $ testSession " extern mulit line doc" $ do
5293
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5294
+ [ " module A where"
5295
+ , " foo = i"
5296
+ ]
5297
+ let expected = " *Imported from 'Prelude'*\n * * *\n\n\n Identity function. \n ```haskell\n id x = x\n ```\n "
5298
+ test doc (Position 1 7 ) " id" (Just $ T. length expected) [expected]
5299
+ , testSession " extern defined doc" $ do
5300
+ doc <- createDoc " A.hs" " haskell" $ T. unlines
5301
+ [ " module A where"
5302
+ , " foo = i"
5303
+ ]
5304
+ let expected = " *Imported from 'Prelude'*\n "
5305
+ test doc (Position 1 7 ) " id" (Just $ T. length expected) [expected]
5306
+ ]
5307
+ where
5308
+ brokenForGhc9 = knownBrokenFor (BrokenForGHC [GHC90 , GHC92 ]) " Completion doc doesn't support ghc9"
5309
+ brokenForWinGhc9 = knownBrokenFor (BrokenSpecific Windows [GHC90 , GHC92 ]) " Extern doc doesn't support Windows for ghc9.2"
5310
+ -- https://gitlab.haskell.org/ghc/ghc/-/issues/20903
5311
+ brokenForMacGhc9 = knownBrokenFor (BrokenSpecific MacOS [GHC90 , GHC92 ]) " Extern doc doesn't support MacOS for ghc9"
5312
+ test doc pos label mn expected = do
5313
+ _ <- waitForDiagnostics
5314
+ compls <- getCompletions doc pos
5315
+ let compls' = [
5316
+ -- We ignore doc uris since it points to the local path which determined by specific machines
5317
+ case mn of
5318
+ Nothing -> txt
5319
+ Just n -> T. take n txt
5320
+ | CompletionItem {_documentation = Just (CompletionDocMarkup (MarkupContent MkMarkdown txt)), .. } <- compls
5321
+ , _label == label
5322
+ ]
5323
+ liftIO $ compls' @?= expected
5324
+
5233
5325
highlightTests :: TestTree
5234
5326
highlightTests = testGroup " highlight"
5235
5327
[ testSessionWait " value" $ do
@@ -5483,32 +5575,61 @@ xfail :: TestTree -> String -> TestTree
5483
5575
xfail = flip expectFailBecause
5484
5576
5485
5577
ignoreInWindowsBecause :: String -> TestTree -> TestTree
5486
- ignoreInWindowsBecause
5487
- | isWindows = ignoreTestBecause
5488
- | otherwise = \ _ x -> x
5578
+ ignoreInWindowsBecause = ignoreFor (BrokenForOS Windows )
5489
5579
5490
5580
ignoreInWindowsForGHC88And810 :: TestTree -> TestTree
5491
- ignoreInWindowsForGHC88And810
5492
- | ghcVersion `elem` [GHC88 , GHC810 ] =
5493
- ignoreInWindowsBecause " tests are unreliable in windows for ghc 8.8 and 8.10"
5494
- | otherwise = id
5581
+ ignoreInWindowsForGHC88And810 =
5582
+ ignoreFor (BrokenSpecific Windows [GHC88 , GHC810 ]) " tests are unreliable in windows for ghc 8.8 and 8.10"
5495
5583
5496
5584
ignoreForGHC92 :: String -> TestTree -> TestTree
5497
- ignoreForGHC92 msg
5498
- | ghcVersion == GHC92 = ignoreTestBecause msg
5499
- | otherwise = id
5585
+ ignoreForGHC92 = ignoreFor (BrokenForGHC [GHC92 ])
5500
5586
5501
5587
ignoreInWindowsForGHC88 :: TestTree -> TestTree
5502
- ignoreInWindowsForGHC88
5503
- | ghcVersion == GHC88 =
5504
- ignoreInWindowsBecause " tests are unreliable in windows for ghc 8.8"
5505
- | otherwise = id
5588
+ ignoreInWindowsForGHC88 =
5589
+ ignoreFor (BrokenSpecific Windows [GHC88 ]) " tests are unreliable in windows for ghc 8.8"
5506
5590
5507
5591
knownBrokenForGhcVersions :: [GhcVersion ] -> String -> TestTree -> TestTree
5508
- knownBrokenForGhcVersions ghcVers
5509
- | ghcVersion `elem` ghcVers = expectFailBecause
5510
- | otherwise = \ _ x -> x
5592
+ knownBrokenForGhcVersions ghcVers = knownBrokenFor (BrokenForGHC ghcVers)
5593
+
5594
+ data BrokenOS = Linux | MacOS | Windows deriving (Show )
5595
+
5596
+ data IssueSolution = Broken | Ignore deriving (Show )
5597
+
5598
+ data BrokenTarget =
5599
+ BrokenSpecific BrokenOS [GhcVersion ]
5600
+ -- ^ Broken for `BrokenOS` with `GhcVersion`
5601
+ | BrokenForOS BrokenOS
5602
+ -- ^ Broken for `BrokenOS`
5603
+ | BrokenForGHC [GhcVersion ]
5604
+ -- ^ Broken for `GhcVersion`
5605
+ deriving (Show )
5606
+
5607
+ -- | Ignore test for specific os and ghc with reason.
5608
+ ignoreFor :: BrokenTarget -> String -> TestTree -> TestTree
5609
+ ignoreFor = knownIssueFor Ignore
5610
+
5611
+ -- | Known broken for specific os and ghc with reason.
5612
+ knownBrokenFor :: BrokenTarget -> String -> TestTree -> TestTree
5613
+ knownBrokenFor = knownIssueFor Broken
5614
+
5615
+ -- | Deal with `IssueSolution` for specific OS and GHC.
5616
+ knownIssueFor :: IssueSolution -> BrokenTarget -> String -> TestTree -> TestTree
5617
+ knownIssueFor solution = go . \ case
5618
+ BrokenSpecific bos vers -> isTargetOS bos && isTargetGhc vers
5619
+ BrokenForOS bos -> isTargetOS bos
5620
+ BrokenForGHC vers -> isTargetGhc vers
5621
+ where
5622
+ isTargetOS = \ case
5623
+ Windows -> isWindows
5624
+ MacOS -> isMac
5625
+ Linux -> not isWindows && not isMac
5626
+
5627
+ isTargetGhc = elem ghcVersion
5511
5628
5629
+ go True = case solution of
5630
+ Broken -> expectFailBecause
5631
+ Ignore -> ignoreTestBecause
5632
+ go False = \ _ -> id
5512
5633
5513
5634
data Expect
5514
5635
= ExpectRange Range -- Both gotoDef and hover should report this range
0 commit comments