on master help sign in
finish test for verifying the parsing of the keys read from the capabilities file
commitf9619d04eb648008eee92c43c445fb16e331bce5 authorCorey O'Connor <corey@ooyala.com> dateTue 22 Oct 2013, 17:48 (13 years ago) parent22774a9
4 files changed+55−57
src/Graphics/Vty/Input.hs+2−2 src/Graphics/Vty/Input/Internal.hs+22−17 test/VerifyUsingMockInput.hs+28−36 vty.cabal+3−2
src/Graphics/Vty/Input.hs+2−2
@@ -15,7 +15,7 @@ import Graphics.Vty.Input.Terminfo
1515import Data.Char
1616import Data.Word
1717
18−import Control.Monad (when)
18+import Control.Monad (when, void)
1919import Control.Concurrent
2020import Control.Exception
2121
@@ -85,7 +85,7 @@ initTermInput escDelay terminal = do
8585 term_event_classify_table = concat $ caps_legacy_table : ansi_classify_table
8686 term_event_classifier = classify term_event_classify_table
8787
88− eventThreadId <- forkIO $ inputToEventThread term_event_classifier inputChannel eventChannel
88+ eventThreadId <- forkIO $ void $ inputToEventThread term_event_classifier inputChannel eventChannel
8989 inputThreadId <- forkIO $ inputThread
9090 noInputThreadId <- forkIO $ noInputThread
9191 let pokeIO = Catch $ do
src/Graphics/Vty/Input/Internal.hs+22−17
@@ -17,10 +17,14 @@ inputToEventThread classifier inputChannel eventChannel = loop []
1717 where loop kb = case (classifier kb) of
1818 Prefix -> do
1919 c <- readChan inputChannel
20− loop (kb ++ [c])
20+ if c == '\xFFFD'
21+ then return ()
22+ else loop (kb ++ [c])
2123 Invalid -> do
2224 c <- readChan inputChannel
23− loop [c]
25+ if c == '\xFFFD'
26+ then return ()
27+ else loop [c]
2428 EndLoop -> return ()
2529 MisPfx k m s -> writeChan eventChannel (EvKey k m) >> loop s
2630 Valid k m -> writeChan eventChannel (EvKey k m) >> loop ""
@@ -28,25 +32,26 @@ inputToEventThread classifier inputChannel eventChannel = loop []
2832compile :: ClassifyTable -> [Char] -> KClass
2933compile table = cl' where
3034 -- take all prefixes and create a set of these
31− -- including inserting [] into the set many times.. hm
3235 prefix_set = S.fromList $ concatMap (init . inits . fst) $ table
3336 -- create a map from strings to event
3437 event_for_input = flip M.lookup (M.fromList table)
38+ cl' [] = Prefix
3539 cl' input_block = case S.member input_block prefix_set of
36− True -> Prefix
37− -- if the input_block is exactly what is expected for an event then consume the whole block
38− -- and return the event
39− False -> case event_for_input input_block of
40− Just (k,m) -> Valid k m
41− -- look up progressively large prefixes of the input block until an event is found
42− -- H: There will always be one match. The prefix_set contains, by definition, all
43− -- prefixes of an event.
44− Nothing ->
45− let input_prefixes = init $ inits input_block
46− in case mapMaybe (\s -> (,) s `fmap` event_for_input s) input_prefixes of
47− (s,(k,m)) : _ -> MisPfx k m (drop (length s) input_block)
48− [] -> error $ "vty internal inconsistency - input not a prefix nor contains any event data "
49− ++ show input_block
40+ True -> Prefix
41+ -- if the input_block is exactly what is expected for an event then consume the whole
42+ -- block and return the event
43+ False -> case event_for_input input_block of
44+ Just (k,m) -> Valid k m
45+ -- look up progressively large prefixes of the input block until an event is found
46+ -- H: There will always be one match. The prefix_set contains, by definition, all
47+ -- prefixes of an event.
48+ Nothing ->
49+ let input_prefixes = init $ inits input_block
50+ in case mapMaybe (\s -> (,) s `fmap` event_for_input s) input_prefixes of
51+ (s,(k,m)) : _ -> MisPfx k m (drop (length s) input_block)
52+ [] -> error $ "vty internal inconsistency - "
53+ ++ "input not a prefix nor contains any event data "
54+ ++ show input_block
5055
5156classify, classifyTab :: ClassifyTable -> [Char] -> KClass
5257
test/VerifyUsingMockInput.hs+28−36
@@ -23,7 +23,6 @@ import Control.Monad
2323
2424import System.Console.Terminfo
2525import System.IO
26−import System.Posix.Env
2726
2827import Test.Framework.Providers.SmallCheck
2928import Test.Framework
@@ -36,6 +35,7 @@ max_bytes_size = 16
3635data InputEvent
3736 = Bytes String -- | input sequence encoded as a string. Regardless, the input is read a byte at a time.
3837 | Delay Int -- | millisecond delay
38+ deriving Show
3939
4040type InputSpec = [InputEvent]
4141
@@ -49,46 +49,38 @@ exec_input_spec input out_handle = forM_ input f
4949
5050assert_events_from_input_block :: ClassifyTable -> InputSpec -> ExpectedSpec -> IO Bool
5151assert_events_from_input_block table input_spec expected_events = do
52+ print input_spec
5253 let classifier = classify table
5354 input <- newChan
5455 output <- newChan
55− forkIO $ write_input_spec_to_chan input input_spec
56− inputToEventThread classifier input output
57− -- H: all events are available in output channel
58− -- TODO: switch to using explicit control events. Currently the channel is passing around a
59− -- magic FFFX characters
56+ read_complete <- newEmptyMVar
57+ write_complete <- newEmptyMVar
58+ _ <- forkIO $ write_input_spec_to_chan input input_spec
59+ `finally` putMVar write_complete ()
60+ _ <- forkIO $ inputToEventThread classifier input output
61+ `finally` putMVar read_complete ()
62+ () <- takeMVar write_complete
63+ () <- takeMVar read_complete
6064 -- TODO: use STM channel
61− let collect_events = handle (\(e :: BlockedIndefinitelyOnMVar) -> return [])
62− ((:) <$> readChan output <*> collect_events)
63− out_events <- collect_events
65+ -- assures the next line does not block.
66+ writeList2Chan output $ replicate (length expected_events) undefined
67+ out_events <- take (length expected_events) <$> getChanContents output
6468 return $ out_events == expected_events
6569
6670write_input_spec_to_chan :: Chan Char -> InputSpec -> IO ()
67−write_input_spec_to_chan chan [] = writeChan chan '\xFFFD'
68−write_input_spec_to_chan chan (Bytes str : input_spec')
69− = writeList2Chan chan str >> write_input_spec_to_chan chan input_spec'
70−write_input_spec_to_chan chan (Delay t : input_spec')
71− = writeChan chan '\xFFFE' >> write_input_spec_to_chan chan input_spec'
72−
73−{-
74−
75−tests :: IO [Test]
76−tests = do
77− mappend
78− <$> pure [ verify "basic block generated from single ansi chars to event translation" ]
79− <*> mapM terminals_of_interest
80− verify_simple_input_block_to_event
81− , verify "keys from caps table are parsed to the same key"
82− verify_keys_from_caps_table
83− ]
84−-}
85−
86−-- how to make this data dependent?
71+write_input_spec_to_chan chan [] = do
72+ writeChan chan '\xFFFD'
73+write_input_spec_to_chan chan (Bytes str : input_spec') = do
74+ writeList2Chan chan str
75+ write_input_spec_to_chan chan input_spec'
76+write_input_spec_to_chan chan (Delay _t : input_spec') = do
77+ writeChan chan '\xFFFE'
78+ write_input_spec_to_chan chan input_spec'
8779
8880newtype EventBlock event = EventBlock ([(String,event)] -> [(String, event)])
8981
9082instance Show (EventBlock event) where
91− show (EventBlock g) = "EventBlock(* -> *)"
83+ show (EventBlock g) = "EventBlock(*->*)"
9284
9385instance Monad m => Serial m (EventBlock event) where
9486 series = do
@@ -106,12 +98,12 @@ verify_keys_from_caps_table_block_to_event :: Property IO
10698verify_keys_from_caps_table_block_to_event = forAll $ \(EventBlock block_gen) ->
10799 over (generate (\n -> take n terminals_of_interest)) $ \term_name -> monadic $ do
108100 terminal <- setupTerm term_name
109− let caps_seq :: [(String, Event)] = block_gen keys_from_caps_table
110− let bytes_seq = caps_classify_table terminal caps_seq
111− input = [Bytes s | (s,_) <- bytes_seq]
112− escaped_sequence = intersperse (Delay defaultEscDelay) input
113− return True :: IO Bool
114− -- cap <- elements keys_from_caps_table
101+ let table = caps_classify_table terminal keys_from_caps_table
102+ input_seq :: [(String, Event)] = block_gen table
103+ input_bytes = [Bytes s | (s,_) <- input_seq]
104+ input = intersperse (Delay defaultEscDelay) input_bytes
105+ events = [e | (_,e) <- input_seq]
106+ assert_events_from_input_block (map_to_legacy_table table) input events
115107
116108main = defaultMain
117109 [ testProperty "basic block generated from a single ansi chars to event translation"
vty.cabal+3−2
@@ -95,9 +95,9 @@ library
9595 default-extensions: ScopedTypeVariables
9696 ForeignFunctionInterface
9797
98− ghc-options: -O2 -funbox-strict-fields -Wall -fno-full-laziness -fspec-constr -fspec-constr-count=10
98+ ghc-options: -O2 -funbox-strict-fields -threaded -Wall -fspec-constr -fspec-constr-count=10
9999
100− ghc-prof-options: -O2 -funbox-strict-fields -caf-all -Wall -fno-full-laziness -fspec-constr -fspec-constr-count=10
100+ ghc-prof-options: -O2 -funbox-strict-fields -threaded -caf-all -Wall -fspec-constr -fspec-constr-count=10
101101
102102 cc-options: -O2
103103
@@ -534,6 +534,7 @@ test-suite verify-using-mock-input
534534 utf8-string >= 0.3 && < 0.4,
535535 vector >= 0.7
536536
537+ ghc-options: -threaded -Wall
537538
538539executable vty-interactive-terminal-test
539540 main-is: interactive_terminal_test.hs