1module Language.PureScript.Ide.FilterSpec where
2
3import           Protolude
4import qualified Data.Map as Map
5import qualified Data.Set as Set
6import           Language.PureScript.Ide.Filter
7import           Language.PureScript.Ide.Filter.Declaration as D
8import           Language.PureScript.Ide.Types
9import           Language.PureScript.Ide.Test as T
10import qualified Language.PureScript as P
11import           Test.Hspec
12
13type Module = (P.ModuleName, [IdeDeclarationAnn])
14
15moduleA, moduleB, moduleC, moduleD, moduleE, moduleF, moduleG, moduleH, moduleI :: Module
16moduleA = (P.moduleNameFromString "Module.A", [T.ideValue "function1" Nothing])
17moduleB = (P.moduleNameFromString "Module.B", [T.ideValue "data1" Nothing])
18moduleC = (P.moduleNameFromString "Module.C", [T.ideType "List" Nothing []])
19moduleD = (P.moduleNameFromString "Module.D", [T.ideType "kind1" Nothing []])
20moduleE = (P.moduleNameFromString "Module.E", [T.ideSynonym "SFType" Nothing Nothing `annLoc` synonymSS])
21moduleF = (P.moduleNameFromString "Module.F", [T.ideDtor "DtorA" "TypeA" Nothing])
22moduleG = (P.moduleNameFromString "Module.G", [T.ideTypeClass "MyClass" P.kindType []])
23moduleH = (P.moduleNameFromString "Module.H", [T.ideValueOp "<$>" (P.Qualified Nothing (Left "")) 0 Nothing Nothing])
24moduleI = (P.moduleNameFromString "Module.I", [T.ideTypeOp "~>" (P.Qualified Nothing "") 0 Nothing Nothing])
25
26modules :: ModuleMap [IdeDeclarationAnn]
27modules = Map.fromList [moduleA, moduleB]
28
29runEq :: Text -> [Module]
30runEq s = Map.toList (applyFilters [exactFilter s] modules)
31
32runPrefix :: Text -> [Module]
33runPrefix s = Map.toList $ applyFilters [prefixFilter s] modules
34
35runModule :: [P.ModuleName] -> [Module]
36runModule ms = Map.toList $ applyFilters [moduleFilter (Set.fromList ms)] modules
37
38runNamespace :: Set IdeNamespace -> [Module] -> [Module]
39runNamespace namespaces = Map.toList . applyFilters [namespaceFilter namespaces] . Map.fromList
40
41runDeclaration :: [D.DeclarationType] -> [Module] -> [Module]
42runDeclaration decls = Map.toList . applyFilters [declarationTypeFilter (Set.fromList decls)] . Map.fromList
43
44spec :: Spec
45spec = do
46  describe "equality Filter" $ do
47    it "removes empty modules" $
48      runEq "test" `shouldBe` []
49    it "keeps function declarations that are equal" $
50      runEq "function1" `shouldBe` [moduleA]
51    it "keeps data declarations that are equal" $
52      runEq "data1" `shouldBe` [moduleB]
53  describe "prefixFilter" $ do
54    it "keeps everything on empty string" $
55      runPrefix "" `shouldBe` Map.toList modules
56    it "keeps functionname prefix matches" $
57      runPrefix "fun" `shouldBe` [moduleA]
58    it "keeps data decls prefix matches" $
59      runPrefix "dat" `shouldBe` [moduleB]
60  describe "moduleFilter" $ do
61    it "removes everything on empty input" $
62      runModule [] `shouldBe` []
63    it "only keeps the specified modules" $
64      runModule [P.moduleNameFromString "Module.A"] `shouldBe` [moduleA]
65    it "ignores modules that are not in scope" $
66      runModule (P.moduleNameFromString <$> ["Module.A", "Unknown"]) `shouldBe` [moduleA]
67  describe "namespaceFilter" $ do
68    it "extracts modules by filtering `value` namespaces" $
69      runNamespace (Set.fromList [IdeNSValue])
70        [moduleA, moduleB, moduleD] `shouldBe` [moduleA, moduleB]
71    it "extracts no modules by filtering `value` namespaces" $
72      runNamespace (Set.fromList [IdeNSValue])
73        [moduleD] `shouldBe` []
74    it "extracts modules by filtering `type` namespaces" $
75      runNamespace (Set.fromList [IdeNSType])
76        [moduleA, moduleB, moduleC] `shouldBe` [moduleC]
77    it "extracts no modules by filtering `type` namespaces" $
78      runNamespace (Set.fromList [IdeNSType])
79        [moduleA, moduleB] `shouldBe` []
80    it "extracts modules by filtering `value` and `type` namespaces" $
81      runNamespace (Set.fromList [ IdeNSValue, IdeNSType])
82        [moduleA, moduleB, moduleC, moduleD]
83        `shouldBe` [moduleA, moduleB, moduleC, moduleD]
84  describe "declarationTypeFilter" $ do
85    it "extracts modules by filtering `value` declarations" $
86      runDeclaration [D.Value]
87        [moduleA, moduleB, moduleD] `shouldBe` [moduleA, moduleB]
88    it "removes everything if no `value` declarations has been found" $
89      runDeclaration [D.Value]
90        [moduleD, moduleG, moduleE, moduleH] `shouldBe` []
91    it "extracts module by filtering `type` declarations" $
92      runDeclaration [D.Type]
93        [moduleA, moduleB, moduleC, moduleD, moduleE] `shouldBe` [moduleC, moduleD]
94    it "removes everything if a `type` declaration have not been found" $
95      runDeclaration [D.Type]
96        [moduleA, moduleG, moduleE, moduleH] `shouldBe` []
97    it "extracts module by filtering `synonym` declarations" $
98      runDeclaration [D.Synonym]
99        [moduleA, moduleB, moduleD, moduleE] `shouldBe` [moduleE]
100    it "removes everything if a `synonym` declaration have not been found" $
101      runDeclaration [D.Synonym]
102        [moduleA, moduleB, moduleC, moduleH] `shouldBe` []
103    it "extracts module by filtering `constructor` declarations" $
104      runDeclaration [D.DataConstructor]
105        [moduleA, moduleB, moduleC, moduleF] `shouldBe` [moduleF]
106    it "removes everything if a `constructor` declaration have not been found" $
107      runDeclaration [D.DataConstructor]
108        [moduleA, moduleB, moduleC, moduleH] `shouldBe` []
109    it "extracts module by filtering `typeclass` declarations" $
110      runDeclaration [D.TypeClass]
111        [moduleA, moduleC, moduleG] `shouldBe` [moduleG]
112    it "removes everything if a `typeclass` declaration have not been found" $
113      runDeclaration [D.TypeClass]
114        [moduleA, moduleB, moduleC, moduleH] `shouldBe` []
115    it "extracts modules by filtering `valueoperator` declarations" $
116      runDeclaration [D.ValueOperator]
117        [moduleA, moduleC, moduleG, moduleH, moduleF] `shouldBe` [moduleH]
118    it "removes everything if a `valueoperator` declaration have not been found" $
119      runDeclaration [D.ValueOperator]
120        [moduleA, moduleB, moduleC, moduleD] `shouldBe` []
121    it "extracts modules by filtering `typeoperator` declarations" $
122      runDeclaration [D.TypeOperator]
123        [moduleA, moduleC, moduleG, moduleI, moduleF] `shouldBe` [moduleI]
124    it "removes everything if a `typeoperator` declaration have not been found" $
125      runDeclaration [D.TypeOperator]
126        [moduleA, moduleD] `shouldBe` []
127    it "extracts modules by filtering `value` and `synonym` declarations" $
128      runDeclaration [D.Value, D.Synonym]
129        [moduleA, moduleB, moduleD, moduleE] `shouldBe` [moduleA, moduleB, moduleE]
130    it "extracts modules by filtering `value`, and `valueoperator` declarations" $
131      runDeclaration [D.Value, D.ValueOperator]
132        [moduleA, moduleB, moduleD, moduleG, moduleE, moduleH] `shouldBe` [moduleA, moduleB, moduleH]
133