lsp-2.0.0.0: test/DiagnosticsSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module DiagnosticsSpec where
import qualified Data.Map as Map
import qualified Data.HashMap.Strict as HM
import qualified Data.SortedList as SL
import Data.Text (Text)
import Language.LSP.Diagnostics
import qualified Language.LSP.Protocol.Types as LSP
import Test.Hspec
{-# ANN module ("HLint: ignore Redundant do" :: String) #-}
-- ---------------------------------------------------------------------
main :: IO ()
main = hspec spec
spec :: Spec
spec = describe "Diagnostics functions" diagnosticsSpec
-- -- |Used when running from ghci, and it sets the current directory to ./tests
-- tt :: IO ()
-- tt = do
-- cd ".."
-- hspec spec
-- ---------------------------------------------------------------------
mkDiagnostic :: Maybe Text -> Text -> LSP.Diagnostic
mkDiagnostic ms str =
let
rng = LSP.Range (LSP.Position 0 1) (LSP.Position 3 0)
loc = LSP.Location (LSP.Uri "file") rng
in
LSP.Diagnostic rng Nothing Nothing Nothing ms str Nothing (Just [LSP.DiagnosticRelatedInformation loc str]) Nothing
mkDiagnostic2 :: Maybe Text -> Text -> LSP.Diagnostic
mkDiagnostic2 ms str =
let
rng = LSP.Range (LSP.Position 4 1) (LSP.Position 5 0)
loc = LSP.Location (LSP.Uri "file") rng
in LSP.Diagnostic rng Nothing Nothing Nothing ms str Nothing (Just [LSP.DiagnosticRelatedInformation loc str]) Nothing
-- ---------------------------------------------------------------------
diagnosticsSpec :: Spec
diagnosticsSpec = do
describe "constructs a new store" $ do
it "constructs a store with no doc version and a single source" $ do
let
diags =
[ mkDiagnostic (Just "hlint") "a"
, mkDiagnostic (Just "hlint") "b"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
(updateDiagnostics HM.empty uri Nothing (partitionBySource diags)) `shouldBe`
HM.fromList
[ (uri,StoreItem Nothing $ Map.fromList [(Just "hlint", SL.toSortedList diags) ] )
]
-- ---------------------------------
it "constructs a store with no doc version and multiple sources" $ do
let
diags =
[ mkDiagnostic (Just "hlint") "a"
, mkDiagnostic (Just "ghcmod") "b"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
(updateDiagnostics HM.empty uri Nothing (partitionBySource diags)) `shouldBe`
HM.fromList
[ (uri,StoreItem Nothing $ Map.fromList
[(Just "hlint", SL.singleton (mkDiagnostic (Just "hlint") "a"))
,(Just "ghcmod", SL.singleton (mkDiagnostic (Just "ghcmod") "b"))
])
]
-- ---------------------------------
it "constructs a store with doc version and multiple sources" $ do
let
diags =
[ mkDiagnostic (Just "hlint") "a"
, mkDiagnostic (Just "ghcmod") "b"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
(updateDiagnostics HM.empty uri (Just 1) (partitionBySource diags)) `shouldBe`
HM.fromList
[ (uri,StoreItem (Just 1) $ Map.fromList
[(Just "hlint", SL.singleton (mkDiagnostic (Just "hlint") "a"))
,(Just "ghcmod", SL.singleton (mkDiagnostic (Just "ghcmod") "b"))
])
]
-- ---------------------------------
describe "updates a store for same document version" $ do
it "updates a store without a document version, single source only" $ do
let
diags1 =
[ mkDiagnostic (Just "hlint") "a1"
, mkDiagnostic (Just "hlint") "b1"
]
diags2 =
[ mkDiagnostic (Just "hlint") "a2"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let origStore = updateDiagnostics HM.empty uri Nothing (partitionBySource diags1)
(updateDiagnostics origStore uri Nothing (partitionBySource diags2)) `shouldBe`
HM.fromList
[ (uri,StoreItem Nothing $ Map.fromList [(Just "hlint", SL.toSortedList diags2) ] )
]
-- ---------------------------------
it "updates just one source of a 2 source store" $ do
let
diags1 =
[ mkDiagnostic (Just "hlint") "a1"
, mkDiagnostic (Just "ghcmod") "b1"
]
diags2 =
[ mkDiagnostic (Just "hlint") "a2"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let origStore = updateDiagnostics HM.empty uri Nothing (partitionBySource diags1)
(updateDiagnostics origStore uri Nothing (partitionBySource diags2)) `shouldBe`
HM.fromList
[ (uri,StoreItem Nothing $ Map.fromList
[(Just "hlint", SL.singleton (mkDiagnostic (Just "hlint") "a2"))
,(Just "ghcmod", SL.singleton (mkDiagnostic (Just "ghcmod") "b1"))
] )
]
-- ---------------------------------
it "updates just one source of a 2 source store, with empty diags" $ do
let
diags1 =
[ mkDiagnostic (Just "hlint") "a1"
, mkDiagnostic (Just "ghcmod") "b1"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let origStore = updateDiagnostics HM.empty uri Nothing (partitionBySource diags1)
(updateDiagnostics origStore uri Nothing (Map.fromList [(Just "ghcmod",SL.toSortedList [])])) `shouldBe`
HM.fromList
[ (uri,StoreItem Nothing $ Map.fromList
[(Just "ghcmod", SL.toSortedList [])
,(Just "hlint", SL.singleton (mkDiagnostic (Just "hlint") "a1"))
] )
]
-- ---------------------------------
describe "updates a store for a new document version" $ do
it "updates a store without a document version, single source only" $ do
let
diags1 =
[ mkDiagnostic (Just "hlint") "a1"
, mkDiagnostic (Just "hlint") "b1"
]
diags2 =
[ mkDiagnostic (Just "hlint") "a2"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let origStore = updateDiagnostics HM.empty uri (Just 1) (partitionBySource diags1)
(updateDiagnostics origStore uri (Just 2) (partitionBySource diags2)) `shouldBe`
HM.fromList
[ (uri,StoreItem (Just 2) $ Map.fromList [(Just "hlint", SL.toSortedList diags2) ] )
]
-- ---------------------------------
it "updates a store for a new doc version, removing all priot sources" $ do
let
diags1 =
[ mkDiagnostic (Just "hlint") "a1"
, mkDiagnostic (Just "ghcmod") "b1"
]
diags2 =
[ mkDiagnostic (Just "hlint") "a2"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let origStore = updateDiagnostics HM.empty uri (Just 1) (partitionBySource diags1)
(updateDiagnostics origStore uri (Just 2) (partitionBySource diags2)) `shouldBe`
HM.fromList
[ (uri,StoreItem (Just 2) $ Map.fromList
[(Just "hlint", SL.singleton (mkDiagnostic (Just "hlint") "a2"))
] )
]
-- ---------------------------------
describe "retrieves all the diagnostics for a given uri" $ do
it "gets diagnostics for multiple sources" $ do
let
diags =
[ mkDiagnostic (Just "hlint") "a"
, mkDiagnostic (Just "ghcmod") "b"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let ds = updateDiagnostics HM.empty uri (Just 1) (partitionBySource diags)
getDiagnosticParamsFor 10 ds uri `shouldBe`
Just (LSP.PublishDiagnosticsParams (LSP.fromNormalizedUri uri) (Just 1) (reverse diags))
-- ---------------------------------
describe "limits the number of diagnostics retrieved, in order" $ do
it "gets diagnostics for multiple sources" $ do
let
diags =
[ mkDiagnostic2 (Just "hlint") "a"
, mkDiagnostic2 (Just "ghcmod") "b"
, mkDiagnostic (Just "hlint") "c"
, mkDiagnostic (Just "ghcmod") "d"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let ds = updateDiagnostics HM.empty uri (Just 1) (partitionBySource diags)
getDiagnosticParamsFor 2 ds uri `shouldBe`
Just (LSP.PublishDiagnosticsParams (LSP.fromNormalizedUri uri) (Just 1)
[
mkDiagnostic (Just "ghcmod") "d"
, mkDiagnostic (Just "hlint") "c"
])
getDiagnosticParamsFor 1 ds uri `shouldBe`
Just (LSP.PublishDiagnosticsParams (LSP.fromNormalizedUri uri) (Just 1)
[
mkDiagnostic (Just "ghcmod") "d"
])
-- ---------------------------------
describe "flushes the diagnostics for a given source" $ do
it "gets diagnostics for multiple sources" $ do
let
diags =
[ mkDiagnostic2 (Just "hlint") "a"
, mkDiagnostic2 (Just "ghcmod") "b"
, mkDiagnostic (Just "hlint") "c"
, mkDiagnostic (Just "ghcmod") "d"
]
uri = LSP.toNormalizedUri $ LSP.Uri "uri"
let ds = updateDiagnostics HM.empty uri (Just 1) (partitionBySource diags)
getDiagnosticParamsFor 100 ds uri `shouldBe`
Just (LSP.PublishDiagnosticsParams (LSP.fromNormalizedUri uri) (Just 1)
[
mkDiagnostic (Just "ghcmod") "d"
, mkDiagnostic (Just "hlint") "c"
, mkDiagnostic2 (Just "ghcmod") "b"
, mkDiagnostic2 (Just "hlint") "a"
])
let ds' = flushBySource ds (Just "hlint")
getDiagnosticParamsFor 100 ds' uri `shouldBe`
Just (LSP.PublishDiagnosticsParams (LSP.fromNormalizedUri uri) (Just 1)
[
mkDiagnostic (Just "ghcmod") "d"
, mkDiagnostic2 (Just "ghcmod") "b"
])
-- ---------------------------------