@@ -57,7 +57,7 @@ import Test.Tasty.Ingredients.Rerun
57
57
import Test.Tasty.HUnit
58
58
import Test.Tasty.QuickCheck
59
59
import System.Time.Extra
60
- import Development.IDE.Plugin.CodeAction (typeSignatureCommandId , blockCommandId )
60
+ import Development.IDE.Plugin.CodeAction (typeSignatureCommandId , blockCommandId , matchRegExMultipleImports )
61
61
import Development.IDE.Plugin.Test (TestRequest (BlockSeconds ,GetInterfaceFilesDir ))
62
62
63
63
main :: IO ()
@@ -97,6 +97,8 @@ main = do
97
97
, rootUriTests
98
98
, asyncTests
99
99
, clientSettingsTest
100
+
101
+ , codeActionHelperFunctionTests
100
102
]
101
103
102
104
initializeResponseTests :: TestTree
@@ -560,6 +562,13 @@ codeActionTests = testGroup "code actions"
560
562
, exportUnusedTests
561
563
]
562
564
565
+ codeActionHelperFunctionTests :: TestTree
566
+ codeActionHelperFunctionTests = testGroup " code action helpers"
567
+ [
568
+ extendImportTestsRegEx
569
+ ]
570
+
571
+
563
572
codeLensesTests :: TestTree
564
573
codeLensesTests = testGroup " code lenses"
565
574
[ addSigLensesTests
@@ -954,139 +963,186 @@ removeImportTests = testGroup "remove import actions"
954
963
extendImportTests :: TestTree
955
964
extendImportTests = testGroup " extend import actions"
956
965
[ testSession " extend single line import with value" $ template
957
- ( T. unlines
966
+ [( " ModuleA.hs " , T. unlines
958
967
[ " module ModuleA where"
959
968
, " stuffA :: Double"
960
969
, " stuffA = 0.00750"
961
970
, " stuffB :: Integer"
962
971
, " stuffB = 123"
963
- ])
964
- (T. unlines
972
+ ])]
973
+ (" ModuleB.hs " , T. unlines
965
974
[ " module ModuleB where"
966
975
, " import ModuleA as A (stuffB)"
967
976
, " main = print (stuffA, stuffB)"
968
977
])
969
978
(Range (Position 3 17 ) (Position 3 18 ))
970
- " Add stuffA to the import list of ModuleA"
979
+ [ " Add stuffA to the import list of ModuleA" ]
971
980
(T. unlines
972
981
[ " module ModuleB where"
973
982
, " import ModuleA as A (stuffA, stuffB)"
974
983
, " main = print (stuffA, stuffB)"
975
984
])
976
985
, testSession " extend single line import with operator" $ template
977
- ( T. unlines
986
+ [( " ModuleA.hs " , T. unlines
978
987
[ " module ModuleA where"
979
988
, " (.*) :: Integer -> Integer -> Integer"
980
989
, " x .* y = x * y"
981
990
, " stuffB :: Integer"
982
991
, " stuffB = 123"
983
- ])
984
- (T. unlines
992
+ ])]
993
+ (" ModuleB.hs " , T. unlines
985
994
[ " module ModuleB where"
986
995
, " import ModuleA as A (stuffB)"
987
996
, " main = print (stuffB .* stuffB)"
988
997
])
989
998
(Range (Position 3 17 ) (Position 3 18 ))
990
- " Add .* to the import list of ModuleA"
999
+ [ " Add .* to the import list of ModuleA" ]
991
1000
(T. unlines
992
1001
[ " module ModuleB where"
993
1002
, " import ModuleA as A ((.*), stuffB)"
994
1003
, " main = print (stuffB .* stuffB)"
995
1004
])
996
1005
, testSession " extend single line import with type" $ template
997
- ( T. unlines
1006
+ [( " ModuleA.hs " , T. unlines
998
1007
[ " module ModuleA where"
999
1008
, " type A = Double"
1000
- ])
1001
- (T. unlines
1009
+ ])]
1010
+ (" ModuleB.hs " , T. unlines
1002
1011
[ " module ModuleB where"
1003
1012
, " import ModuleA ()"
1004
1013
, " b :: A"
1005
1014
, " b = 0"
1006
1015
])
1007
1016
(Range (Position 2 5 ) (Position 2 5 ))
1008
- " Add A to the import list of ModuleA"
1017
+ [ " Add A to the import list of ModuleA" ]
1009
1018
(T. unlines
1010
1019
[ " module ModuleB where"
1011
1020
, " import ModuleA (A)"
1012
1021
, " b :: A"
1013
1022
, " b = 0"
1014
1023
])
1015
1024
, (`xfail` " known broken" ) $ testSession " extend single line import with constructor" $ template
1016
- ( T. unlines
1025
+ [( " ModuleA.hs " , T. unlines
1017
1026
[ " module ModuleA where"
1018
1027
, " data A = Constructor"
1019
- ])
1020
- (T. unlines
1028
+ ])]
1029
+ (" ModuleB.hs " , T. unlines
1021
1030
[ " module ModuleB where"
1022
1031
, " import ModuleA (A)"
1023
1032
, " b :: A"
1024
1033
, " b = Constructor"
1025
1034
])
1026
1035
(Range (Position 2 5 ) (Position 2 5 ))
1027
- " Add Constructor to the import list of ModuleA"
1036
+ [ " Add Constructor to the import list of ModuleA" ]
1028
1037
(T. unlines
1029
1038
[ " module ModuleB where"
1030
1039
, " import ModuleA (A(Constructor))"
1031
1040
, " b :: A"
1032
1041
, " b = Constructor"
1033
1042
])
1034
1043
, testSession " extend single line qualified import with value" $ template
1035
- ( T. unlines
1044
+ [( " ModuleA.hs " , T. unlines
1036
1045
[ " module ModuleA where"
1037
1046
, " stuffA :: Double"
1038
1047
, " stuffA = 0.00750"
1039
1048
, " stuffB :: Integer"
1040
1049
, " stuffB = 123"
1041
- ])
1042
- (T. unlines
1050
+ ])]
1051
+ (" ModuleB.hs " , T. unlines
1043
1052
[ " module ModuleB where"
1044
1053
, " import qualified ModuleA as A (stuffB)"
1045
1054
, " main = print (A.stuffA, A.stuffB)"
1046
1055
])
1047
1056
(Range (Position 3 17 ) (Position 3 18 ))
1048
- " Add stuffA to the import list of ModuleA"
1057
+ [ " Add stuffA to the import list of ModuleA" ]
1049
1058
(T. unlines
1050
1059
[ " module ModuleB where"
1051
1060
, " import qualified ModuleA as A (stuffA, stuffB)"
1052
1061
, " main = print (A.stuffA, A.stuffB)"
1053
1062
])
1054
1063
, testSession " extend multi line import with value" $ template
1055
- ( T. unlines
1064
+ [( " ModuleA.hs " , T. unlines
1056
1065
[ " module ModuleA where"
1057
1066
, " stuffA :: Double"
1058
1067
, " stuffA = 0.00750"
1059
1068
, " stuffB :: Integer"
1060
1069
, " stuffB = 123"
1061
- ])
1062
- (T. unlines
1070
+ ])]
1071
+ (" ModuleB.hs " , T. unlines
1063
1072
[ " module ModuleB where"
1064
1073
, " import ModuleA (stuffB"
1065
1074
, " )"
1066
1075
, " main = print (stuffA, stuffB)"
1067
1076
])
1068
1077
(Range (Position 3 17 ) (Position 3 18 ))
1069
- " Add stuffA to the import list of ModuleA"
1078
+ [ " Add stuffA to the import list of ModuleA" ]
1070
1079
(T. unlines
1071
1080
[ " module ModuleB where"
1072
1081
, " import ModuleA (stuffA, stuffB"
1073
1082
, " )"
1074
1083
, " main = print (stuffA, stuffB)"
1075
1084
])
1085
+ , testSession " extend import list with multiple choices" $ template
1086
+ [(" ModuleA.hs" , T. unlines
1087
+ -- this is just a dummy module to help the arguments needed for this test
1088
+ [ " module ModuleA (bar) where"
1089
+ , " bar = 10"
1090
+ ]),
1091
+ (" ModuleB.hs" , T. unlines
1092
+ -- this is just a dummy module to help the arguments needed for this test
1093
+ [ " module ModuleB (bar) where"
1094
+ , " bar = 10"
1095
+ ])]
1096
+ (" ModuleC.hs" , T. unlines
1097
+ [ " module ModuleC where"
1098
+ , " import ModuleB ()"
1099
+ , " import ModuleA ()"
1100
+ , " foo = bar"
1101
+ ])
1102
+ (Range (Position 3 17 ) (Position 3 18 ))
1103
+ [" Add bar to the import list of ModuleA" ,
1104
+ " Add bar to the import list of ModuleB" ]
1105
+ (T. unlines
1106
+ [ " module ModuleC where"
1107
+ , " import ModuleB ()"
1108
+ , " import ModuleA (bar)"
1109
+ , " foo = bar"
1110
+ ])
1076
1111
]
1077
1112
where
1078
- template contentA contentB range expectedAction expectedContentB = do
1079
- _docA <- createDoc " ModuleA.hs" " haskell" contentA
1080
- docB <- createDoc " ModuleB.hs" " haskell" contentB
1081
- _ <- waitForDiagnostics
1082
- CACodeAction action@ CodeAction { _title = actionTitle } : _
1083
- <- sortOn (\ (CACodeAction CodeAction {_title= x}) -> x) <$>
1084
- getCodeActions docB range
1085
- liftIO $ expectedAction @=? actionTitle
1113
+ template setUpModules moduleUnderTest range expectedActions expectedContentB = do
1114
+ mapM_ (\ x -> createDoc (fst x) " haskell" (snd x)) setUpModules
1115
+ docB <- createDoc (fst moduleUnderTest) " haskell" (snd moduleUnderTest)
1116
+ _ <- waitForDiagnostics
1117
+ codeActions <- filter (\ (CACodeAction CodeAction {_title= x}) -> T. isPrefixOf " Add" x)
1118
+ <$> getCodeActions docB range
1119
+ let expectedTitles = (\ (CACodeAction CodeAction {_title= x}) -> x) <$> codeActions
1120
+ liftIO $ expectedActions @=? expectedTitles
1121
+
1122
+ -- Get the first action and execute the first action
1123
+ let CACodeAction action : _
1124
+ = sortOn (\ (CACodeAction CodeAction {_title= x}) -> x) codeActions
1086
1125
executeCodeAction action
1087
1126
contentAfterAction <- documentContents docB
1088
1127
liftIO $ expectedContentB @=? contentAfterAction
1089
1128
1129
+ extendImportTestsRegEx :: TestTree
1130
+ extendImportTestsRegEx = testGroup " regex parsing"
1131
+ [
1132
+ testCase " parse invalid multiple imports" $ template " foo bar foo" Nothing
1133
+ , testCase " parse malformed import list" $ template
1134
+ " \n \8226 Perhaps you want to add \8216fromList\8217 to one of these import lists:\n \8216Data.Map\8217)"
1135
+ Nothing
1136
+ , testCase " parse multiple imports" $ template
1137
+ " \n \8226 Perhaps you want to add \8216fromList\8217 to one of these import lists:\n \8216Data.Map\8217 (app/testlsp.hs:7:1-18)\n \8216Data.HashMap.Strict\8217 (app/testlsp.hs:8:1-29)"
1138
+ $ Just (" fromList" ,[(" Data.Map" ," app/testlsp.hs:7:1-18" ),(" Data.HashMap.Strict" ," app/testlsp.hs:8:1-29" )])
1139
+ ]
1140
+ where
1141
+ template message expected = do
1142
+ liftIO $ matchRegExMultipleImports message @=? expected
1143
+
1144
+
1145
+
1090
1146
suggestImportTests :: TestTree
1091
1147
suggestImportTests = testGroup " suggest import actions"
1092
1148
[ testGroup " Dont want suggestion"
0 commit comments