@@ -272,6 +272,7 @@ codeActionTests = testGroup "code actions"
272272 , removeImportTests
273273 , importRenameActionTests
274274 , fillTypedHoleTests
275+ , addSigActionTests
275276 ]
276277
277278renameActionTests :: TestTree
@@ -515,7 +516,7 @@ fillTypedHoleTests = let
515516 check :: T.Text -> T.Text -> T.Text -> T.Text -> T.Text -> T.Text -> T.Text -> TestTree
516517 check actionTitle
517518 oldA oldB oldC
518− newA newB newC = testSession (T.unpack actionTitle) $ do
519+ newA newB newC = testSession (T.unpack actionTitle) $ do
519520 let originalCode = sourceCode oldA oldB oldC
520521 let expectedCode = sourceCode newA newB newC
521522 doc <- openDoc' "Testing.hs" "haskell" originalCode
@@ -525,12 +526,6 @@ fillTypedHoleTests = let
525526 executeCodeAction chosenAction
526527 modifiedCode <- documentContents doc
527528 liftIO $ expectedCode @=? modifiedCode
528−
529− pickActionWithTitle title actions = head
530− [ action
531− | CACodeAction action@CodeAction{ _title = actionTitle } <- actions
532− , title == actionTitle ]
533−
534529 in
535530 testGroup "fill typed holes"
536531 [ check "replace hole `_` with show"
@@ -562,6 +557,33 @@ fillTypedHoleTests = let
562557#endif
563558 ]
564559
560+addSigActionTests :: TestTree
561+addSigActionTests = let
562+ head = T.unlines [ "{-# OPTIONS_GHC -Wmissing-signatures #-}"
563+ , "module Sigs where"]
564+ before def = T.unlines [head, def]
565+ after def sig = T.unlines [head, sig, def]
566+
567+ def >:: sig = testSession (T.unpack def) $ do
568+ let originalCode = before def
569+ let expectedCode = after def sig
570+ doc <- openDoc' "Sigs.hs" "haskell" originalCode
571+ _ <- waitForDiagnostics
572+ actionsOrCommands <- getCodeActions doc (Range (Position 3 1) (Position 3 maxBound))
573+ let chosenAction = pickActionWithTitle ("add signature: " <> sig) actionsOrCommands
574+ executeCodeAction chosenAction
575+ modifiedCode <- documentContents doc
576+ liftIO $ expectedCode @=? modifiedCode
577+ in
578+ testGroup "add signature"
579+ [ "abc = True" >:: "abc :: Bool"
580+ , "foo a b = a + b" >:: "foo :: Num a => a -> a -> a"
581+ , "bar a b = show $ a + b" >:: "bar :: (Show a, Num a) => a -> a -> String"
582+ , "(!!!) a b = a > b" >:: "(!!!) :: Ord a => a -> a -> Bool"
583+ , "a >>>> b = a + b" >:: "(>>>>) :: Num a => a -> a -> a"
584+ , "a `haha` b = a b" >:: "haha :: (t1 -> t2) -> t1 -> t2"
585+ ]
586+
565587----------------------------------------------------------------------
566588-- Utils
567589
@@ -577,6 +599,11 @@ testSession name =
577599 -- Experimentally, 0.5s seems to be long enough to wait for any final diagnostics to appear.
578600 ( >> expectNoMoreDiagnostics 0.5)
579601
602+pickActionWithTitle :: T.Text -> [CAResult] -> CodeAction
603+pickActionWithTitle title actions = head
604+ [ action
605+ | CACodeAction action@CodeAction{ _title = actionTitle } <- actions
606+ , title == actionTitle ]
580607
581608run :: Session a -> IO a
582609run s = withTempDir $ \dir -> do