   [ "line input" ~: utf8Test iFile
        [utf8 "xαβyψ안기q영\nquit\n"]
        [ prompt' 0, output 0 (utf8 "xαβyψ안기q영") <> prompt' 1]
    , "char input" ~: utf8Test iFileChar
        [utf8 "xαβt"]
        [ prompt' 0
        , output 0 (utf8 "x")
            <> prompt' 1 <> output 1 (utf8 "α")
            <> prompt' 2 <> output 2 (utf8 "β")
            <> prompt' 3 <> output 3 (utf8 "t")
            <> prompt' 4]
    , "invalid line input" ~: utf8Test iFile
        -- NOTE: the 206 is an incomplete byte sequence,
        -- but we MUST not pause since we're at EOF, not just
        -- end of term.
        --
        -- Also recall GHC bug #5436 which caused a crash
        -- if the last byte started an incomplete sequence.
        [ utf8 "a" <> raw [149] <> utf8 "x" <> raw [206] ]
        [ prompt' 0
        , B.empty
        -- It only prompts after the EOF.
        , output 0 (utf8 "a" <> err <> utf8 "x" <> err) <> prompt' 1
        ]
    , "invalid char input (following a newline)" ~: utf8Test iFileChar
        [ utf8 "a\n" <> raw [149] <> utf8 "x\n" <> raw [206] ]
        $ [ prompt' 0
          , output 0 (utf8 "a")
             <> prompt' 1 <> output 1 err
             <> prompt' 2 <> output 2 (utf8 "x")
             <> prompt' 3
             <> whenLegacy (output 3 err <> prompt' 4)
          ] ++ if legacyEncoding then [] else [ output 3 err <> prompt' 4 ]
    , "invalid char file input (no preceding newline)" ~: utf8Test iFileChar
        [ utf8 "a" <> raw [149] <> utf8 "x" <> raw [206] ]
            -- make sure it tries to read a newline
            -- and instead gets the incomplete 206.
            -- This should *not* cause it to crash or block.
        $ [ prompt' 0
          , output 0 (utf8 "a")
             <> prompt' 1 <> output 1 err
             <> prompt' 2 <> output 2 (utf8 "x")
             <> prompt' 3
             <> whenLegacy (output 3 err <> prompt' 4)
          ] ++ if legacyEncoding then [] else [ output 3 err <> prompt' 4 ]
     ]
    -- also single char and buffer break and other stuff
  where
    iFile = i { runInTTY = False }
    iFileChar = setCharInput iFile

-- Test that the dumb terminal backend does encoding correctly.
-- If all the above tests work for the terminfo backend,
-- then we just need to make sure the dumb term plugs into everything
-- correctly, i.e., encodes the input/output and doesn't double-encode.
dumbTests :: Invocation -> Test
dumbTests i = "dumb term" ~:
    [ "line input" ~: utf8Test i

fileStyleTests :: Invocation -> Test
fileStyleTests i = "file style" ~:
    [ "line input" ~: utf8Test iFile
        [utf8 "xαβyψ안기q영\nquit\n"]
        [ prompt' 0, output 0 (utf8 "xαβyψ안기q영") <> prompt' 1]
    , "char input" ~: utf8Test iFileChar
        [utf8 "xαβt"]
        [ prompt' 0
        , output 0 (utf8 "x")
            <> prompt' 1 <> output 1 (utf8 "α")
            <> prompt' 2 <> output 2 (utf8 "β")
            <> prompt' 3 <> output 3 (utf8 "t")
            <> prompt' 4]
    , "invalid line input" ~: utf8Test iFile
        -- NOTE: the 206 is an incomplete byte sequence,
        -- but we MUST not pause since we're at EOF, not just
        -- end of term.
        --
        -- Also recall GHC bug #5436 which caused a crash
        -- if the last byte started an incomplete sequence.
        [ utf8 "a" <> raw [149] <> utf8 "x" <> raw [206] ]
        [ prompt' 0
        , B.empty
        -- It only prompts after the EOF.
        , output 0 (utf8 "a" <> err <> utf8 "x" <> err) <> prompt' 1
        ]
    , "invalid char input (following a newline)" ~: utf8Test iFileChar
        [ utf8 "a\n" <> raw [149] <> utf8 "x\n" <> raw [206] ]
        $ [ prompt' 0
          , output 0 (utf8 "a")
             <> prompt' 1 <> output 1 err
             <> prompt' 2 <> output 2 (utf8 "x")
             <> prompt' 3
             <> whenLegacy (output 3 err <> prompt' 4)
          ] ++ if legacyEncoding then [] else [ output 3 err <> prompt' 4 ]
    , "invalid char file input (no preceding newline)" ~: utf8Test iFileChar
        [ utf8 "a" <> raw [149] <> utf8 "x" <> raw [206] ]
            -- make sure it tries to read a newline
            -- and instead gets the incomplete 206.
            -- This should *not* cause it to crash or block.
        $ [ prompt' 0
          , output 0 (utf8 "a")
             <> prompt' 1 <> output 1 err
             <> prompt' 2 <> output 2 (utf8 "x")
             <> prompt' 3
             <> whenLegacy (output 3 err <> prompt' 4)
          ] ++ if legacyEncoding then [] else [ output 3 err <> prompt' 4 ]
     ]
    -- also single char and buffer break and other stuff
  where
    iFile = i { runInTTY = False }
    iFileChar = setCharInput iFile

-- Test that the dumb terminal backend does encoding correctly.
-- If all the above tests work for the terminfo backend,
-- then we just need to make sure the dumb term plugs into everything
-- correctly, i.e., encodes the input/output and doesn't double-encode.
fileStyleTests i = "file style" ~:
    [ "line input" ~: utf8Test iFile
        [utf8 "xαβyψ안기q영\nquit\n"]
        [ prompt' 0, output 0 (utf8 "xαβyψ안기q영") <> prompt' 1]
    , "char input" ~: utf8Test iFileChar
        [utf8 "xαβt"]
        [ prompt' 0
        , output 0 (utf8 "x")
            <> prompt' 1 <> output 1 (utf8 "α")
            <> prompt' 2 <> output 2 (utf8 "β")
            <> prompt' 3 <> output 3 (utf8 "t")
            <> prompt' 4]
    , "invalid line input" ~: utf8Test iFile
        -- NOTE: the 206 is an incomplete byte sequence,
        -- but we MUST not pause since we're at EOF, not just
        -- end of term.
        --
        -- Also recall GHC bug #5436 which caused a crash
        -- if the last byte started an incomplete sequence.
        [ utf8 "a" <> raw [149] <> utf8 "x" <> raw [206] ]
        [ prompt' 0
        , B.empty
        -- It only prompts after the EOF.
        , output 0 (utf8 "a" <> err <> utf8 "x" <> err) <> prompt' 1
        ]
    , "invalid char input (following a newline)" ~: utf8Test iFileChar
        [ utf8 "a\n" <> raw [149] <> utf8 "x\n" <> raw [206] ]
        $ [ prompt' 0
          , output 0 (utf8 "a")
             <> prompt' 1 <> output 1 err
             <> prompt' 2 <> output 2 (utf8 "x")
             <> prompt' 3
             <> whenLegacy (output 3 err <> prompt' 4)
          ] ++ if legacyEncoding then [] else [ output 3 err <> prompt' 4 ]
    , "invalid char file input (no preceding newline)" ~: utf8Test iFileChar
        [ utf8 "a" <> raw [149] <> utf8 "x" <> raw [206] ]
            -- make sure it tries to read a newline
            -- and instead gets the incomplete 206.
            -- This should *not* cause it to crash or block.
        $ [ prompt' 0
          , output 0 (utf8 "a")
             <> prompt' 1 <> output 1 err
             <> prompt' 2 <> output 2 (utf8 "x")
             <> prompt' 3
             <> whenLegacy (output 3 err <> prompt' 4)
          ] ++ if legacyEncoding then [] else [ output 3 err <> prompt' 4 ]
     ]
    -- also single char and buffer break and other stuff
  where
    iFile = i { runInTTY = False }
    iFileChar = setCharInput iFile

-- Test that the dumb terminal backend does encoding correctly.
-- If all the above tests work for the terminfo backend,
-- then we just need to make sure the dumb term plugs into everything
-- correctly, i.e., encodes the input/output and doesn't double-encode.