1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
{-# LANGUAGE OverloadedStrings #-}
module Ormolu.OpTreeSpec (spec) where
import Data.Map.Strict qualified as Map
import Data.Text (Text)
import Data.Text qualified as T
import GHC.Types.Name (mkOccName, varName)
import GHC.Types.Name.Reader (mkRdrUnqual)
import Ormolu.Fixity
import Ormolu.Fixity.Internal
import Ormolu.Printer.Operators
import Test.Hspec
n :: Text -> OpTree Text OpName
n = OpNode
-- | Check that the input tree is actually reassociated as expected.
checkReassociate ::
-- | Fixity map used for the reassociation
[(OpName, FixityInfo)] ->
-- | Input tree
OpTree Text OpName ->
-- | Expected output tree
OpTree Text OpName ->
Expectation
checkReassociate fixities inputTree expectedOutputTree =
removeOpInfo actualOutputTree `shouldBe` expectedOutputTree
where
removeOpInfo (OpNode x) = OpNode x
removeOpInfo (OpBranches exprs ops) =
OpBranches (removeOpInfo <$> exprs) (opiOp <$> ops)
actualOutputTree = reassociateOpTree convertName modFixityMap inputTree
modFixityMap = ModuleFixityMap (Map.map Given (Map.fromList fixities))
convertName = Just . mkRdrUnqual . mkOccName varName . T.unpack . unOpName
spec :: Spec
spec = do
it "flattens a tree correctly" $ do
let inputTree =
OpBranches
[ OpBranches
[OpBranches [n "a", n "b"] ["+"], n "c"]
["+"],
n "d"
]
["+"]
outputTree =
OpBranches [n "a", n "b", n "c", n "d"] ["+", "+", "+"]
fixities = [("+", FixityInfo InfixL 5)]
checkReassociate fixities inputTree outputTree
it "uses 'minOps' strategy by default" $ do
let inputTree =
OpBranches
[n "a", n "b", n "c", n "d", n "e", n "f"]
["*", "*", "+", "*", "-"]
outputTree =
OpBranches
[ OpBranches [n "a", n "b", n "c"] ["*", "*"],
OpBranches [n "d", n "e"] ["*"],
n "f"
]
["+", "-"]
fixities =
[ ("+", FixityInfo InfixL 5),
("*", FixityInfo InfixL 7),
("-", FixityInfo InfixL 5)
]
checkReassociate fixities inputTree outputTree
it "uses 'maxOps' strategy if 'minOps' strategy fails" $ do
let inputTree =
OpBranches
[n "a", n "b", n "c", n "d", n "e", n "f"]
["*", "*", "+", "*", "-"]
outputTree =
OpBranches
[ OpBranches [n "a", n "b", n "c"] ["*", "*"],
OpBranches [n "d", n "e"] ["*"],
n "f"
]
["+", "-"]
fixities =
[ ("+", FixityInfo InfixL 5),
("*", FixityInfo InfixL 8),
("-", FixityInfo InfixL 5)
]
checkReassociate fixities inputTree outputTree
it
"defaults to 'hardSplitter' strategy if both 'minOps' and 'maxOps' \
\strategies fail"
$ do
let inputTree =
OpBranches
[n "a", n "b", n "c", n "d", n "e", n "f"]
["@", "@", "|", "@", "$"]
outputTree =
OpBranches
[ OpBranches
[n "a", n "b", n "c", n "d", n "e"]
["@", "@", "|", "@"],
n "f"
]
["$"]
fixities =
[ ("@", FixityInfo InfixL 4),
("|", FixityInfo InfixL 4),
("$", FixityInfo InfixR 0)
]
checkReassociate fixities inputTree outputTree
it "reassociates correctly: complex example 1" $ do
let inputTree =
OpBranches
[n "f", n "1", n "2", n "3", n "4", n "5", n "6"]
["$", "+", "*", "$", "*", "+"]
outputTree =
OpBranches
[ n "f",
OpBranches
[n "1", OpBranches [n "2", n "3"] ["*"]]
["+"],
OpBranches
[OpBranches [n "4", n "5"] ["*"], n "6"]
["+"]
]
["$", "$"]
fixities =
[ ("$", FixityInfo InfixR 0),
("+", FixityInfo InfixL 6),
("*", FixityInfo InfixL 7)
]
checkReassociate fixities inputTree outputTree
|