aboutsummaryrefslogtreecommitdiffstats
path: root/tests/Selective.hs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Selective.hs')
-rw-r--r--tests/Selective.hs87
1 files changed, 87 insertions, 0 deletions
diff --git a/tests/Selective.hs b/tests/Selective.hs
new file mode 100644
index 0000000..db00563
--- /dev/null
+++ b/tests/Selective.hs
@@ -0,0 +1,87 @@
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# LANGUAGE ScopedTypeVariables, FlexibleInstances #-}
+module Selective where
+
+-- Tests for limitSelect-related code in L.LimitWindows.
+-- To run these tests, export (select,update,Selection(..),updateAndSelect) from
+-- L.LimitWindows.
+
+import XMonad.Layout.LimitWindows
+import XMonad.StackSet hiding (focusUp, focusDown, filter)
+import Control.Applicative ((<$>))
+import Test.QuickCheck
+import Control.Arrow (second)
+
+instance Arbitrary (Stack Int) where
+ arbitrary = do
+ xs <- arbNat
+ ys <- arbNat
+ return $ Stack { up=[xs-1,xs-2..0], focus=xs, down=[xs+1..xs+ys] }
+ coarbitrary = undefined
+
+instance Arbitrary (Selection a) where
+ arbitrary = do
+ nm <- arbNat
+ st <- arbNat
+ nr <- arbPos
+ return $ Sel nm (st+nm) nr
+ coarbitrary = undefined
+
+arbNat = abs <$> arbitrary
+arbPos = (+1) . abs <$> arbitrary
+
+-- as many windows as possible should be selected
+-- (when the selection is normalized)
+prop_select_length sel (stk :: Stack Int) =
+ (length . integrate $ select sel' stk) == ((nMaster sel' + nRest sel') `min` length (integrate stk))
+ where sel' = update sel stk
+
+-- update normalizes selections (is idempotent)
+prop_update_idem sel (stk :: Stack Int) = sel' == update sel' stk
+ where sel' = update sel stk
+
+-- select selects the master pane
+prop_select_master sel (stk :: Stack Int) =
+ take (nMaster sel) (integrate stk) == take (nMaster sel) (integrate $ select sel stk)
+
+-- the focus should always be selected in normalized selections
+prop_select_focus sel (stk :: Stack Int) = focus stk == (focus $ select sel' stk)
+ where sel' = update sel stk
+
+-- select doesn't change order (or duplicate elements)
+-- relies on the Arbitrary instance for Stack Int generating increasing stacks
+prop_select_increasing sel (stk :: Stack Int) =
+ let res = integrate $ select sel stk
+ in and . zipWith (<) res $ tail res
+
+-- selection has the form [0..l] ++ [m..n]
+-- relies on the Arbitrary instance for Stack Int generating stacks like [0..k]
+prop_select_two_consec sel (stk :: Stack Int) =
+ let wins = integrate $ select sel stk
+ in (length . filter not . zipWith ((==) . (+1)) wins $ tail wins) <= 1
+
+-- update preserves invariants on selections
+prop_update_nm sel (stk :: Stack Int) = nMaster (update sel stk) >= 0
+prop_update_start sel (stk :: Stack Int) = nMaster sel' <= start sel'
+ where sel' = update sel stk
+prop_update_nr sel (stk :: Stack Int) = nRest (update sel stk) >= 0
+
+-- moving the focus to a window that's already selected doesn't change the selection
+prop_update_focus_up sel (stk :: Stack Int) x' =
+ (length (up stk) >= x) && ((up stk !! (x-1)) `elem` integrate stk') ==>
+ sel' == update sel' (iterate focusUp stk !! x)
+ where
+ x = 1 + abs x'
+ sel' = update sel stk
+ stk' = select sel' stk
+
+prop_update_focus_down sel (stk :: Stack Int) x' =
+ (length (down stk) >= x) && ((down stk !! (x-1)) `elem` integrate stk') ==>
+ sel' == update sel' (iterate focusDown stk !! x)
+ where
+ x = 1 + abs x'
+ sel' = update sel stk
+ stk' = select sel' stk
+
+focusUp stk = stk { up=tail (up stk), focus=head (up stk), down=focus stk:down stk }
+focusDown stk = stk { down=tail (down stk), focus=head (down stk), up=focus stk:up stk }