{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} module Class ( tests ) where import Control.Applicative.Combinators import Control.Lens hiding ((<.>)) import Control.Monad.IO.Class (MonadIO (liftIO)) import qualified Data.ByteString.Lazy as BS import qualified Data.Text.Encoding as T import Language.LSP.Test import Language.LSP.Types hiding (_command, _title) import qualified Language.LSP.Types.Lens as J import System.FilePath import Test.Hls.Util import Test.Tasty import Test.Tasty.Golden import Test.Tasty.HUnit tests :: TestTree tests = testGroup "class" [ testCase "Produces addMinimalMethodPlaceholders code actions for one instance" $ do runSession hlsCommand fullCaps classPath $ do doc <- openDoc "T1.hs" "haskell" _ <- waitForDiagnosticsFromSource doc "typecheck" caResults <- getAllCodeActions doc liftIO $ map (^? _CACodeAction . J.title) caResults @?= [ Just "Add placeholders for '=='" , Just "Add placeholders for '/='" , Just "Disable \"missing-methods\" warnings" ] , glodenTest "Creates a placeholder for '=='" "T1" "eq" $ \(eqAction:_) -> do executeCodeAction eqAction , glodenTest "Creates a placeholder for '/='" "T1" "ne" $ \(_:neAction:_) -> do executeCodeAction neAction , glodenTest "Creates a placeholder for 'fmap'" "T2" "fmap" $ \(_:_:fmapAction:_) -> do executeCodeAction fmapAction , glodenTest "Creates a placeholder for multiple methods 1" "T3" "1" $ \(mmAction:_) -> do executeCodeAction mmAction , glodenTest "Creates a placeholder for multiple methods 2" "T3" "2" $ \(_:mmAction:_) -> do executeCodeAction mmAction , glodenTest "Creates a placeholder for a method starting with '_'" "T4" "" $ \(_fAction:_) -> do executeCodeAction _fAction ] _CACodeAction :: Prism' (Command |? CodeAction) CodeAction _CACodeAction = prism' InR $ \case InR action -> Just action _ -> Nothing classPath :: FilePath classPath = "test" "testdata" "class" glodenTest :: String -> FilePath -> FilePath -> ([CodeAction] -> Session ()) -> TestTree glodenTest name fp deco execute = goldenVsStringDiff name goldenGitDiff (classPath fpWithDeco <.> "expected" <.> "hs") $ runSession hlsCommand fullCaps classPath $ do doc <- openDoc (fp <.> "hs") "haskell" _ <- waitForDiagnosticsFromSource doc "typecheck" actions <- concatMap (^.. _CACodeAction) <$> getAllCodeActions doc execute actions BS.fromStrict . T.encodeUtf8 <$> (skipManyTill anyMessage $ getDocumentEdit doc) where fpWithDeco | deco == "" = fp | otherwise = fp <.> deco goldenGitDiff :: FilePath -> FilePath -> [String] goldenGitDiff fRef fNew = ["git", "diff", "--no-index", "--text", "--exit-code", fRef, fNew]