Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions test/haskell/Test/Integration/Evaluate.hs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
-- | Evaluate request tests (issue #116) ported from the NodeJS testsuite.
-- | Evaluate request tests ported from the NodeJS testsuite.
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Test.Integration.Evaluate (evaluateTests) where

import Control.Monad.IO.Class (liftIO)
import Data.List (isInfixOf)
import Test.DAP
import Test.Tasty
import Test.Tasty.HUnit
#ifdef mingw32_HOST_OS
import Test.Tasty.ExpectedFailure
#endif
import qualified DAP

evaluateTests :: TestTree
Expand All @@ -20,6 +19,11 @@ evaluateTests =
testGroup "DAP.Integration.Evaluate"
[ testCase "Return structured representation for evaluated expressions (issue #116)"
evaluateStructured
, testCase "Imported module bindings available in evaluate context (issue #233)"
evaluateImportedBindings
, expectFailBecause "#299" $
testCase "Bindings from other modules not available in evaluate context (issue #233)"
evaluateImportedBindingsNotInOtherModule
]

evaluateStructured :: Assertion
Expand All @@ -38,3 +42,55 @@ evaluateStructured =
[] -> liftIO $ assertFailure $
"No variable named 1 in evaluation result: " ++ show respChildren
disconnect

-- | Test that bindings from imported modules are available when evaluating
-- expressions at a breakpoint (issue #233).
evaluateImportedBindings :: Assertion
evaluateImportedBindings =
withTestDAPServer "test/integration/T233" [] $ \test_dir server ->
withTestDAPServerClient server $ do
let cfg = mkLaunchConfig test_dir "T233.hs"
hitBreakpointWith cfg 15

-- sort is imported from Data.List
sortResp <- evaluate "show (sort xs)"
liftIO $ assertEqual "sort xs result" "\"[1,1,2,3,4,5,6,9]\"" (DAP.evaluateResponseResult sortResp)

-- Map is a qualified import
mapResp <- evaluate "show (Map.lookup \"a\" m)"
liftIO $ assertEqual "Map.lookup result" "\"Just 1\"" (DAP.evaluateResponseResult mapResp)

disconnect

-- | Test that bindings from modules not imported at the stopped location are
-- NOT available in the evaluate context (issue #233).
evaluateImportedBindingsNotInOtherModule :: Assertion
evaluateImportedBindingsNotInOtherModule =
withTestDAPServer "test/integration/T233" [] $ \test_dir server ->
withTestDAPServerClient server $ do
let cfg = mkLaunchConfig test_dir "T233.hs"

_ <- sync $ launchWith cfg
waitFiltering_ EventTy "initialized"
-- T233.hs imports Data.Map.Strict as Map; Other.hs does not
_ <- sync $ setLineBreakpoints test_dir "T233.hs" [15]
_ <- sync $ setLineBreakpoints test_dir "Other.hs" [4]
_ <- sync configurationDone
_ <- assertStoppedLocation DAP.StoppedEventReasonBreakpoint 15

-- Stopped in T233.hs which imports Data.List and Data.Map.Strict as Map
sortResp <- evaluate "show (sort xs)"
liftIO $ assertEqual "sort xs result" "\"[1,1,2,3,4,5,6,9]\"" (DAP.evaluateResponseResult sortResp)

-- Resume and stop at breakpoint in Other.hs, which does not import Map
continueThread 0
_ <- assertStoppedLocation DAP.StoppedEventReasonBreakpoint 4

-- Map is not imported in Other.hs; evaluating Map.fromList should fail
mapFailResp <- evaluate "Map.fromList [(1,'a')]"
let result = DAP.evaluateResponseResult mapFailResp
liftIO $ assertBool
("expected 'not in scope' error for Map.fromList, got: " ++ show result)
("not in scope" `isInfixOf` show result)

disconnect
6 changes: 6 additions & 0 deletions test/integration/T233/Other.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Other where

process :: [Int] -> IO ()
process xs = do
let n = length xs
print n
17 changes: 17 additions & 0 deletions test/integration/T233/T233.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module Main where

import Data.List (sort, nub)
import qualified Data.Map.Strict as Map
import Other (process)

main :: IO ()
main = do
let xs = [3, 1, 4, 1, 5, 9, 2, 6] :: [Int]
let m = Map.fromList [("a", 1), ("b", 2)] :: Map.Map String Int
check xs m
process xs

check :: [Int] -> Map.Map String Int -> IO ()
check xs m = do
print xs
print m
Loading