How do you test ManageHook using QuickCheck?

Hi, I asked the same question in StackOverflow [1] but since I haven't gotten an answer, let me ask here once again. I guess this mailing list is more appropriate place to ask. I want to test ManageHooks in my xmonad.hs and I've heard there is nice testing library called QuickCheck, so I am trying it. I worte the following code but could not make it work because XConf and XState doesn't have required field. I am not a haskell programmer, so maybe I am doing something wrong. I guess filling everything in XConf and XState means connecting to the X server which is rather heavy for a quick test. It would be better if I can write something like `StackSet i l a s sd -> ManageHook -> Bool`. import XMonad.Core import XMonad.ManageHook (doIgnore) import XMonad.Config (defaultConfig) import qualified XMonad.StackSet as W import Test.QuickCheck (Property, quickCheck) import Test.QuickCheck.Monadic (assert, monadicIO, run) prop_manage_hook :: XConf -> XState -> ManageHook -> Property prop_manage_hook c st mh = monadicIO $ do (_, newst) <- run $ runX c st $ runQuery mh $ theRoot c assert $ length (W.currentTag $ windowset newst) > 0 main :: IO () main = do quickCheck $ prop_manage_hook xc st doIgnore where xc = XConf { config = defaultConfig } st = XState {} I once experienced xmonad halted because of a zero-division error I had in my ManageHooks. That's why I want to test it before putting in my xmonad.hs. [1] http://stackoverflow.com/questions/8552627/how-do-you-test-managehook-using-... Thanks, Takafumi

Hello, On Sun, Feb 05, 2012 at 05:46:50AM +0100, Takafumi Arakaki wrote:
doesn't have required field. I am not a haskell programmer, so maybe I am doing something wrong.
Um, you are putting the cart before the horse. Yes, you don't have to really know Haskell and get away with small hacks to your xmonad config, but what you're doing is not just a small hack... it's a fairly substantial undertaking. So, learn some real Haskell first. That said, here's some feedback on your question... I've only used QuickCheck with pure functions before, sorry.
I once experienced xmonad halted because of a zero-division error I had in my ManageHooks. That's why I want to test it before putting in my xmonad.hs.
You should separate out the pure computations out of your managehook stuff and then use QuickCheck on those functions. A zero-division error sounds like it's from your own code (if not, then you should contact the maintainer(s) of the libraries in question and send a bug report).
prop_manage_hook :: XConf -> XState -> ManageHook -> Property
Also, isn't your code sample missing a Arbitrary typeclass instance? And Property should be PropertyM. Seeing how you've missed these glaring errors, I take it that you do not understand what monads are, and am compelled to reiterate that you should learn Haskell first... -Linus

Thank you Linus,
On Sun, Feb 5, 2012 at 7:00 PM, Linus Arver
You should separate out the pure computations out of your managehook stuff and then use QuickCheck on those functions. A zero-division error sounds like it's from your own code (if not, then you should contact the maintainer(s) of the libraries in question and send a bug report).
I'd like to see the example of separating "the pure computations out of your managehook stuff and then use QuickCheck on those functions". But I suppose it is possible to test the manage hook as is (w/o separating the pure computation part), or it is not? And yes, the zero-division error is in my management hook. I want to learn Haskell and XMonad is interesting project. That's why I tried to start it by hacking XMonad after quickly reading some Haskell web book.

Quoting Takafumi Arakaki
I'd like to see the example of separating "the pure computations out of your managehook stuff and then use QuickCheck on those functions".
The core xmonad code goes to great lengths to keep the bulk of its functionality pure, with a smallish wrapper to communicate with X, and provides a fairly comprehensive QuickCheck test suite. (See the "tests" directory in the repository.) Perhaps you can take some inspiration from there. ~d

Thanks! I had a look at it but since it does not import ManageHook I did not read it seriously. I will try it again.

On Mon, Feb 6, 2012 at 10:38 AM,
The core xmonad code goes to great lengths to keep the bulk of its functionality pure, with a smallish wrapper to communicate with X, and provides a fairly comprehensive QuickCheck test suite. (See the "tests" directory in the repository.) Perhaps you can take some inspiration from there.
~d
The "wrapper to communicate with X" is unfortunately the majority of the code. It should be possible to change the IO functions to ones that manipulate a haskell model of what the X does. Most of the effort would end up going into making sure the model is correct. Some bugs you might be able to find with that approach are situations where xmonad tells X to go through an excess number of steps to get to the final state. This is probably a problem for configs using lots of contrib modules (NoBorders, Decoration, etc.). Adam

On Mon, Feb 06, 2012 at 12:14:18PM +0100, Takafumi Arakaki wrote:
Thank you Linus,
On Sun, Feb 5, 2012 at 7:00 PM, Linus Arver
wrote: You should separate out the pure computations out of your managehook stuff and then use QuickCheck on those functions. A zero-division error sounds like it's from your own code (if not, then you should contact the maintainer(s) of the libraries in question and send a bug report).
I'd like to see the example of separating "the pure computations out of your managehook stuff and then use QuickCheck on those functions". But I suppose it is possible to test the manage hook as is (w/o separating the pure computation part), or it is not? And yes, the zero-division error is in my management hook.
What I meant was, just test the pure (monad-free) code that you added on your own in your managemenet hook stuff. I.e., you should refactor your functions so that the pure parts are separate on their own, and then test these smaller (pure) functions. Here's a tutorial on how to do this: http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck. The "getList" function's type signature there is "IO String", and the tutorial goes on about how to test the pure, smaller parts outside of the IO monad. Testing the manage hook "as is" w/o separating the pure computation part is probably really hard to do... if I'm not mistaken XMonad already uses QuickCheck so you'd have to dig inside the XMonad code for some examples. This is a lot more difficult than just testing pure parts... You could post your managment hook code on this list or the Haskell Beginner's list [1] for more specific pointers. [1] http://www.haskell.org/mailman/listinfo/beginners -Linus

On Wed, Feb 15, 2012 at 2:38 AM, Linus Arver
Testing the manage hook "as is" w/o separating the pure computation part is probably really hard to do... if I'm not mistaken XMonad already uses QuickCheck so you'd have to dig inside the XMonad code for some examples. This is a lot more difficult than just testing pure parts...
Defining manage hook as pure function sounds redundant because I cannot use already defined monadic management hooks inside of that function (maybe I am misunderstanding this part). That's why I wanted to test manage hook "as is". Takafumi
participants (4)
-
adam vogt
-
Linus Arver
-
Takafumi Arakaki
-
wagnerdm@seas.upenn.edu