Skip to content

Commit 888e249

Browse files
committed
add test to prevent phantom dependencies
1 parent c580ff5 commit 888e249

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

hls-graph/test/ActionSpec.hs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33

44
module ActionSpec where
55

6+
import qualified Control.Concurrent as C
67
import Control.Concurrent.STM
7-
import Development.IDE.Graph (shakeOptions)
8-
import Development.IDE.Graph.Database (shakeNewDatabase,
9-
shakeRunDatabase)
8+
import Development.IDE.Graph (shakeOptions)
9+
import Development.IDE.Graph.Database (shakeNewDatabase,
10+
shakeRunDatabase)
11+
import Development.IDE.Graph.Internal.Database (build, incDatabase)
1012
import Development.IDE.Graph.Internal.Key
1113
import Development.IDE.Graph.Internal.Types
1214
import Development.IDE.Graph.Rule
1315
import Example
14-
import qualified StmContainers.Map as STM
16+
import qualified StmContainers.Map as STM
1517
import Test.Hspec
1618

1719
spec :: Spec
@@ -57,6 +59,28 @@ spec = do
5759
addRule $ \(Rule :: Rule ()) _old _mode -> error "boom"
5860
let res = shakeRunDatabase db $ pure $ apply1 (Rule @())
5961
res `shouldThrow` anyErrorCall
62+
it "computes a rule with branching dependencies does not invoke phantom dependencies #3423" $ do
63+
cond <- C.newMVar True
64+
count <- C.newMVar 0
65+
(ShakeDatabase _ _ theDb) <- shakeNewDatabase shakeOptions $ do
66+
ruleUnit
67+
ruleCond cond
68+
ruleSubBranch count
69+
ruleWithCond
70+
-- build the one with the condition True
71+
-- This should call the SubBranchRule once
72+
-- cond rule would return different results each time
73+
res0 <- build theDb emptyStack [BranchedRule]
74+
snd res0 `shouldBe` [1 :: Int]
75+
incDatabase theDb Nothing
76+
-- build the one with the condition False
77+
-- This should not call the SubBranchRule
78+
res1 <- build theDb emptyStack [BranchedRule]
79+
snd res1 `shouldBe` [2 :: Int]
80+
-- SubBranchRule should be recomputed one before this (when the condition was True)
81+
countRes <- build theDb emptyStack [SubBranchRule]
82+
snd countRes `shouldBe` [1 :: Int]
83+
6084
describe "applyWithoutDependency" $ do
6185
it "does not track dependencies" $ do
6286
db@(ShakeDatabase _ _ theDb) <- shakeNewDatabase shakeOptions $ do

hls-graph/test/Example.hs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
{-# LANGUAGE TypeFamilies #-}
55
module Example where
66

7+
import qualified Control.Concurrent as C
8+
import Control.Monad.IO.Class (liftIO)
79
import Development.IDE.Graph
810
import Development.IDE.Graph.Classes
911
import Development.IDE.Graph.Rule
@@ -27,3 +29,36 @@ ruleBool :: Rules ()
2729
ruleBool = addRule $ \Rule _old _mode -> do
2830
() <- apply1 Rule
2931
return $ RunResult ChangedRecomputeDiff "" True
32+
33+
34+
data CondRule = CondRule
35+
deriving (Eq, Generic, Hashable, NFData, Show, Typeable)
36+
type instance RuleResult CondRule = Bool
37+
38+
39+
ruleCond :: C.MVar Bool -> Rules ()
40+
ruleCond mv = addRule $ \CondRule _old _mode -> do
41+
r <- liftIO $ C.modifyMVar mv $ \x -> return (not x, x)
42+
return $ RunResult ChangedRecomputeDiff "" r
43+
44+
data BranchedRule = BranchedRule
45+
deriving (Eq, Generic, Hashable, NFData, Show, Typeable)
46+
type instance RuleResult BranchedRule = Int
47+
48+
ruleWithCond :: Rules ()
49+
ruleWithCond = addRule $ \BranchedRule _old _mode -> do
50+
r <- apply1 CondRule
51+
if r then do
52+
_ <- apply1 SubBranchRule
53+
return $ RunResult ChangedRecomputeDiff "" (1 :: Int)
54+
else
55+
return $ RunResult ChangedRecomputeDiff "" (2 :: Int)
56+
57+
data SubBranchRule = SubBranchRule
58+
deriving (Eq, Generic, Hashable, NFData, Show, Typeable)
59+
type instance RuleResult SubBranchRule = Int
60+
61+
ruleSubBranch :: C.MVar Int -> Rules ()
62+
ruleSubBranch mv = addRule $ \SubBranchRule _old _mode -> do
63+
r <- liftIO $ C.modifyMVar mv $ \x -> return (x+1, x)
64+
return $ RunResult ChangedRecomputeDiff "" r

0 commit comments

Comments
 (0)