debugger-hs-0.1.0.0: test/Test/Debugger/RenderSpec.hs
{-# LANGUAGE QuasiQuotes #-}
module Test.Debugger.RenderSpec
( module Test.Debugger.RenderSpec
) where
import Prelude hiding (break, print)
import qualified Data.Text as T
import Test.Hspec
import NeatInterpolation
import Debugger.Builder
import Debugger.Render
import Debugger.Statement
import Control.Monad.Cont
-- NOTE: 2 $s is to escape the quasiquoter, renders as 1 $
shouldRenderAs :: Builder a -> T.Text -> IO ()
shouldRenderAs script expected =
renderScript (runBuilder script) `shouldBe` expected
spec :: Spec
spec = describe "rendering scripts" $ parallel $ do
it "handles empty scripts" $ do
pure () `shouldRenderAs` ""
it "renders break statements" $ do
break (Function "main") `shouldRenderAs` [text|
break main
set $$var0 = $$bpnum
|]
break (File "./a/b.c" 42) `shouldRenderAs` [text|
break ./a/b.c:42
set $$var0 = $$bpnum
|]
it "renders command statements" $ do
let script = do
bp <- break (Function "main")
command bp $ do
print "42"
continue
script `shouldRenderAs` [text|
break main
set $$var0 = $$bpnum
command $$var0
print "42"
continue
end
|]
it "renders nested command statements" $ do
let script = do
bp1 <- break (Function "main")
command bp1 $ do
bp2 <- break (File "file.cpp" 1234)
command bp2 $ do
print "42"
continue
script `shouldRenderAs` [text|
break main
set $$var0 = $$bpnum
command $$var0
break file.cpp:1234
set $$var1 = $$bpnum
command $$var1
print "42"
continue
end
end
|]
it "renders continue statements" $ do
continue `shouldRenderAs` [text|
continue
|]
it "renders next statements" $ do
let script1 = next
script2 = nextN 10
script1 `shouldRenderAs` [text|
next
|]
script2 `shouldRenderAs` [text|
next 10
|]
it "renders step statements" $ do
let script1 = step
script2 = stepN 10
script1 `shouldRenderAs` [text|
step
|]
script2 `shouldRenderAs` [text|
step 10
|]
it "renders reset statements" $ do
reset `shouldRenderAs` [text|
monitor reset
|]
it "renders set statements" $ do
set "$var" "123" `shouldRenderAs` [text|
set $$var = 123
|]
it "renders call statements" $ do
call "function(123)" `shouldRenderAs` [text|
call function(123)
|]
it "renders delete statements" $ do
let script1 = do
bp <- break (Function "main")
delete bp
script2 = do
bp1 <- break (Function "f")
bp2 <- break (Function "g")
delete [bp1, bp2]
script3 = delete All
script1 `shouldRenderAs` [text|
break main
set $$var0 = $$bpnum
delete $$var0
|]
script2 `shouldRenderAs` [text|
break f
set $$var0 = $$bpnum
break g
set $$var1 = $$bpnum
delete $$var0 $$var1
|]
script3 `shouldRenderAs` [text|
delete
|]
it "renders disable statements" $ do
let script1 = do
bp <- break (Function "main")
disable bp
script2 = do
bp1 <- break (Function "f")
bp2 <- break (Function "g")
disable [bp1, bp2]
script3 = disable All
script1 `shouldRenderAs` [text|
break main
set $$var0 = $$bpnum
disable $$var0
|]
script2 `shouldRenderAs` [text|
break f
set $$var0 = $$bpnum
break g
set $$var1 = $$bpnum
disable $$var0 $$var1
|]
script3 `shouldRenderAs` [text|
disable
|]
it "renders enable statements" $ do
let script1 = do
bp <- break (Function "main")
enable bp
script2 = do
bp1 <- break (Function "f")
bp2 <- break (Function "g")
enable [bp1, bp2]
script3 = enable All
script1 `shouldRenderAs` [text|
break main
set $$var0 = $$bpnum
enable $$var0
|]
script2 `shouldRenderAs` [text|
break f
set $$var0 = $$bpnum
break g
set $$var1 = $$bpnum
enable $$var0 $$var1
|]
script3 `shouldRenderAs` [text|
enable
|]
it "renders print statements" $ do
print "42" `shouldRenderAs` [text|
print "42"
|]
it "renders shell statements" $ do
shell "sleep 1" `shouldRenderAs` [text|
shell sleep 1
|]
it "renders source statements" $ do
source "./other_script.gdb" `shouldRenderAs` [text|
source ./other_script.gdb
|]
it "renders target statements" $ do
let script = target (Remote 9001)
script `shouldRenderAs` [text|
target remote tcp:localhost:9001
|]
it "renders target statements" $ do
let script = info Breakpoints
script `shouldRenderAs` [text|
info breakpoints
|]
it "mixes well with other Haskell concepts" $ do
let script = flip runContT delete $ do
bp1 <- ContT $ withBreakpoint (Function "func1")
bp2 <- ContT $ withBreakpoint (Function "func2")
pure [bp1, bp2]
withBreakpoint :: Location -> (Id -> Builder ()) -> Builder ()
withBreakpoint loc f = do
bp <- break loc
command bp $ f bp
script `shouldRenderAs` [text|
break func1
set $$var0 = $$bpnum
command $$var0
break func2
set $$var1 = $$bpnum
command $$var1
delete $$var0 $$var1
end
end
|]