Search code examples
haskellshake-build-system

How can I write "unit" tests for Shake rules or actions?


I am writing specialised rules and oracles for Shake and I would like to write tests for those functions. How can I do that in Shake? I did not find any simple to use actionToIO function that could do the job.

For example, I would like to test the behaviour of the following :

checkGitWorkDirIsClean = do
  Stdout out <- cmd "git" [ "status", "-s", "-uno" ]
  pure $ null $ filter (/= "") (lines out)

so I could create prepare directories containing minimalistic git data and test the function against those directories.


Solution

  • Generally speaking, testing build systems is hard. Shake has various linting related features that are probably the best way to the the entirety of the build system.

    For testing small fragments, it's best if you can make them in IO rather than Action. In the above case, cmd can be run in both the Action and IO monads, so testing it in IO is probably much easier.

    If you do have fragments in Action the only way to drive that through a Shake build system is using something like the shake function. If you want to do so in a consistent way, often setting shakeFiles to /dev/null can be useful, as that will cause Shake not to write to a database, so every run will be as though Shake was starting from a clean slate.