1{-# LANGUAGE RecordWildCards #-}
2{-# LANGUAGE TupleSections #-}
9import Control.Monad.Trans.State.Strict (runStateT)
10import Control.Monad (when, forM)
11import Control.Monad.Writer.Strict (runWriterT)
12import Control.Monad.Trans.Except (runExceptT)
14import Data.List (sort)
16import System.Exit (exitFailure)
17import System.Console.Haskeline
18import System.FilePath ((</>))
19import System.Directory (getCurrentDirectory)
20import System.IO.UTF8 (readUTF8File)
21import qualified System.FilePath.Glob as Glob
25import qualified Language.PureScript as P
27import PSCi.Module (loadAllModules)
33 Counts{..} <- runTestTT allTests
34 when (errors + failures > 0) exitFailure
37allTests = completionTests
39completionTests :: Test
41 TestLabel "completionTests"
42 (TestList (map (TestCase . assertCompletedOk) completionTestData))
44-- If the cursor is at the right end of the line, with the 1st element of the
45-- pair as the text in the line, then pressing tab should offer all the
46-- elements of the list (which is the 2nd element) as completions.
47completionTestData :: [(String, [String])]
53 , (":mo", [":module"])
56 -- :browse should complete module names
57 , (":b Control.Monad.E", map (":b Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console"])
58 , (":b Control.Monad.Eff.", map (":b Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console"])
60 -- import should complete module names
61 , ("import Control.Monad.E", map ("import Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console"])
62 , ("import Control.Monad.Eff.", map ("import Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console"])
63 , ("import qualified Control.Monad.Eff.", map ("import qualified Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console"])
65 -- :load, :module should complete file paths
66 , (":l tests/support/psci/", [":l tests/support/psci/Sample.purs"])
67 , (":module tests/support/psci/", [":module tests/support/psci/Sample.purs"])
69 -- :quit, :help, :reset should not complete
74 -- :show should complete to "loaded" and "import"
75 , (":show ", [":show import", ":show loaded"])
78 -- :type should complete values and data constructors in scope
79 , (":type Control.Monad.Eff.Console.lo", [":type Control.Monad.Eff.Console.log"])
80 , (":type uni", [":type unit"])
81 , (":type E", [":type EQ"])
83 -- :kind should complete types in scope
84 , (":kind C", [":kind Control.Monad.Eff.Pure"])
85 , (":kind O", [":kind Ordering"])
87 -- Only one argument for directives should be completed
88 , (":show import ", [])
90 , (":kind Ordering ", [])
92 -- a few other import tests
93 , ("impor", ["import"])
94 , ("import q", ["import qualified"])
95 , ("import ", map ("import " ++) supportModules ++ ["import qualified"])
96 , ("import Prelude ", [])
98 -- String and number literals should not be completed
102 -- Identifiers and data constructors should be completed
104 , ("Control.Monad.Eff.Class.", ["Control.Monad.Eff.Class.liftEff"])
106 , ("Prelude.L", ["Prelude.LT"])
108 -- if a module is imported qualified, values should complete under the
109 -- qualified name, as well as the original name.
110 , ("ST.new", ["ST.newSTRef"])
111 , ("Control.Monad.ST.new", ["Control.Monad.ST.newSTRef"])
115assertCompletedOk :: (String, [String]) -> Assertion
116assertCompletedOk (line, expecteds) = do
117 (unusedR, completions) <- runCM (completion' (reverse line, ""))
118 let unused = reverse unusedR
119 let actuals = map ((unused ++) . replacement) completions
120 sort expecteds @=? sort actuals
122runCM :: CompletionM a -> IO a
124 psciState <- getPSCiState
125 fmap fst (runStateT (liftCompletionM act) psciState)
127getPSCiState :: IO PSCiState
129 cwd <- getCurrentDirectory
130 let supportDir = cwd </> "tests" </> "support" </> "flattened"
131 let supportFiles ext = Glob.globDir1 (Glob.compile ("*." ++ ext)) supportDir
132 pursFiles <- supportFiles "purs"
133 jsFiles <- supportFiles "js"
135 modulesOrFirstError <- loadAllModules pursFiles
136 foreignFiles <- forM jsFiles (\f -> (f,) <$> readUTF8File f)
137 Right (foreigns, _) <- runExceptT $ runWriterT $ P.parseForeignModulesFromFiles foreignFiles
138 case modulesOrFirstError of
140 print err >> exitFailure
142 let imports = [controlMonadSTasST, (P.ModuleName [P.ProperName "Prelude"], P.Implicit, Nothing)]
143 in return (mkPSCiState imports modules foreigns [] [])
145controlMonadSTasST :: ImportedModule
146controlMonadSTasST = (s "Control.Monad.ST", P.Implicit, Just (s "ST"))
148 s = P.moduleNameFromString
150supportModules :: [String]
152 [ "Control.Monad.Eff.Class"
153 , "Control.Monad.Eff.Console"
154 , "Control.Monad.Eff"
155 , "Control.Monad.Eff.Unsafe"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list