forked from xmonad/xmonad-contrib
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
xmonad-contrib part of "Make extensibleState primarily keyed by TypeR…
…ep …" We've been using the String we get out of `show . typeOf` as key in `extensibleState`, but that has a somewhat serious bug: it shows unqualified type names, so if two modules use the same type name, their extensible states will be stored in one place and get overwritten all the time. To fix this, the `extensibleState` map is now primarily keyed by the TypeRep themselves, with fallback to String for not yet deserialized data. XMonad.Core now exports `showExtType` which serializes type names qualified, and this is used in `writeStateToFile`. A simpler fix would be to just change the serialization of type names in `XMonad.Util.ExtensibleState`, but I'm afraid that might slows things down: Most types used here will start with "XMonad.", and that's a lot of useless linked-list pointer jumping. Fixes: xmonad#94
- Loading branch information
Showing
4 changed files
with
117 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
{-# LANGUAGE ViewPatterns #-} | ||
{-# OPTIONS_GHC -Wall #-} | ||
module ExtensibleState where | ||
|
||
import Test.Hspec | ||
|
||
import XMonad | ||
import Data.Typeable | ||
import qualified XMonad.Util.ExtensibleState as XS | ||
import qualified Data.Map as M | ||
|
||
data TestState = TestState Int deriving (Show, Read, Eq) | ||
instance ExtensionClass TestState where | ||
initialValue = TestState 0 | ||
|
||
data TestPersistent = TestPersistent Int deriving (Show, Read, Eq) | ||
instance ExtensionClass TestPersistent where | ||
initialValue = TestPersistent 0 | ||
extensionType = PersistentExtension | ||
|
||
spec :: Spec | ||
spec = do | ||
describe "upgrade of non-persistent" $ | ||
it "noop" $ | ||
M.keys (XS.upgrade (undefined :: TestState) mempty) `shouldBe` mempty | ||
describe "upgrade of persistent" $ do | ||
describe "inserts initial value if not found" $ do | ||
let k = Right (typeOf (undefined :: TestPersistent)) | ||
let m = XS.upgrade (undefined :: TestPersistent) mempty | ||
specify "keys" $ M.keys m `shouldBe` [k] | ||
specify "value" $ assertRightPersistent k m (TestPersistent 0) | ||
describe "noop if Right found" $ do | ||
let k = Right (typeOf (undefined :: TestPersistent)) | ||
let m0 = M.singleton k (Right (PersistentExtension (TestPersistent 1))) | ||
let m = XS.upgrade (undefined :: TestPersistent) m0 | ||
specify "keys" $ M.keys m `shouldBe` [k] | ||
specify "value" $ assertRightPersistent k m (TestPersistent 1) | ||
describe "deserialize" $ do | ||
let k0 = Left "ExtensibleState.TestPersistent" | ||
let m0 = M.singleton k0 (Left "TestPersistent 1") | ||
let k = Right (typeOf (undefined :: TestPersistent)) | ||
let m = XS.upgrade (undefined :: TestPersistent) m0 | ||
specify "keys" $ M.keys m `shouldBe` [k] | ||
specify "value" $ assertRightPersistent k m (TestPersistent 1) | ||
describe "upgrade from old representation and deserialize" $ do | ||
let k0 = Left "TestPersistent" | ||
let m0 = M.singleton k0 (Left "TestPersistent 1") | ||
let k = Right (typeOf (undefined :: TestPersistent)) | ||
let m = XS.upgrade (undefined :: TestPersistent) m0 | ||
specify "keys" $ M.keys m `shouldBe` [k] | ||
specify "value" $ assertRightPersistent k m (TestPersistent 1) | ||
|
||
assertRightPersistent :: (Ord k, Typeable v, Show v, Eq v) | ||
=> k -> M.Map k (Either String StateExtension) -> v -> Expectation | ||
assertRightPersistent k m v = case k `M.lookup` m of | ||
Just (Right (PersistentExtension (cast -> Just x))) -> x `shouldBe` v | ||
_ -> expectationFailure "unexpected" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters