{-# LANGUAGE OverloadedStrings #-} module Main (main) where import Control.Lens hiding (List, (<.>)) import Data.ByteString.Lazy (ByteString) import qualified Data.ByteString.Lazy.Char8 as LBSChar8 import Data.String (fromString) import Development.IDE.Types.Logger (Priority (Debug), Recorder (Recorder), WithPriority (WithPriority), makeDefaultStderrRecorder, pretty) import Ide.Plugin.CodeRange (Log, descriptor) import qualified Ide.Plugin.CodeRange.RulesTest import qualified Ide.Plugin.CodeRangeTest import Language.LSP.Types.Lens import System.FilePath ((<.>), ()) import Test.Hls plugin :: Recorder (WithPriority Log) -> PluginDescriptor IdeState plugin recorder = descriptor recorder "codeRange" main :: IO () main = do recorder <- contramap (fmap pretty) <$> makeDefaultStderrRecorder Nothing Debug defaultTestRunner $ testGroup "Code Range" [ testGroup "Integration Tests" [ makeSelectionRangeGoldenTest recorder "Import" [(4, 36), (1, 8)], makeSelectionRangeGoldenTest recorder "Function" [(5, 19), (5, 12), (4, 4), (3, 5)] ], testGroup "Unit Tests" [ Ide.Plugin.CodeRangeTest.testTree, Ide.Plugin.CodeRange.RulesTest.testTree ] ] makeSelectionRangeGoldenTest :: Recorder (WithPriority Log) -> TestName -> [(UInt, UInt)] -> TestTree makeSelectionRangeGoldenTest recorder testName positions = goldenGitDiff testName (testDataDir testName <.> "golden" <.> "txt") $ do res <- runSessionWithServer (plugin recorder) testDataDir $ do doc <- openDoc (testName <.> "hs") "haskell" resp <- request STextDocumentSelectionRange $ SelectionRangeParams Nothing Nothing doc (List $ fmap (uncurry Position . (\(x, y) -> (x-1, y-1))) positions) let res = resp ^. result pure $ fmap showSelectionRangesForTest res case res of Left err -> assertFailure (show err) Right golden -> pure golden where testDataDir :: FilePath testDataDir = "test" "testdata" "selection-range" showSelectionRangesForTest :: List SelectionRange -> ByteString showSelectionRangesForTest (List selectionRanges) = LBSChar8.intercalate "\n" $ fmap showSelectionRangeForTest selectionRanges showSelectionRangeForTest :: SelectionRange -> ByteString showSelectionRangeForTest selectionRange = go True (Just selectionRange) where go :: Bool -> Maybe SelectionRange -> ByteString go _ Nothing = "" go isFirst (Just (SelectionRange (Range sp ep) parent)) = (if isFirst then "" else " => ") <> showPosition sp <> " " <> showPosition ep <> go False parent showPosition :: Position -> ByteString showPosition (Position line col) = "(" <> showLBS (line + 1) <> "," <> showLBS (col + 1) <> ")" showLBS = fromString . show