0

I'm trying to write a (small) executable, setup using Cabal, unit tested using HSpec. Almost all of my code is in a separate module, Library, including the body of main, which I import into my Main module as the run function

-- In src/Hecho.hs
module Main where
import Library(run)

main :: IO ()
main = run

Although the main function is now as short as I think it can be, is there a way I can write a test for it, say to check that it equals the run function, or maybe to test it some other way? The issue is that my spec file defines another Main module, and I don't seem to be able (or at least I can't figure out how) to import anything into it from the other Main module.

For example, if I try the following

-- In test/HechoSpec.hs
module Main where

import Library
import Main
import Test.Hspec

main :: IO ()
main = hspec $ do
  -- Test definitions

Then I get the error:

Module imports form a cycle:
  module `Main' (test/HechoSpec.hs) imports itself

Is there a way to test the main function?

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165

1 Answers1

1

Updated answer: Apparently the question is how to make sure Library.run is the same as main.

The answer is that it's not possible to do that. main is a value of type IO () and there is no Eq defined for IO actions. For instance, this program does not type check:

main = print "Hello"

foo = main

fooEqualsMain = foo == main
ErikR
  • 51,541
  • 9
  • 73
  • 124
  • Removing the `module Main` from my test file has no effect, and I get the same error. From [this answer](http://stackoverflow.com/a/11112455/1319998) it looks like Haskell effectively inserts a `module Main(main)` when a module is not specified. – Michal Charemza Nov 30 '14 at 18:49
  • Ok. Perhaps you can use `AppMain.hs` for you application's main module? – ErikR Nov 30 '14 at 18:56
  • My application's main module is already in a file `Hecho.hs`, and from what I've read, I think the `main` function needs to be in a module named `Main` for it to run when the executable runs. – Michal Charemza Nov 30 '14 at 19:16
  • How about importing `Library` into your test and use the `run` function? You've defined `main = run` in `Hecho.hs` so they are the same function. – ErikR Nov 30 '14 at 19:26
  • I'm already doing that, and I can test the run function, but my aim for this question is to test the `main` function: at least that it equals `run`. – Michal Charemza Nov 30 '14 at 19:32
  • You can't. There is no way to compare two `IO` actions for equality. – ErikR Nov 30 '14 at 19:35
  • Ok, so it's not possible to test it equals something, but is it possible to test what it does? – Michal Charemza Nov 30 '14 at 20:05
  • Well, it creates a small tcp server that just echos out what's passed to it. However, I suspect that's not relevant to my question (although I might have later questions about it!). The main thrust of this question to be able to get `main` accessible to my tests. Your (now edited) answer, of not being able to test IO actions for equality, while quite possibly accurate, is a bit moot, as I can't access `main` from the tests in the first place. – Michal Charemza Nov 30 '14 at 20:54
  • You've define `main` to be `run` from the `Library` module, so why not just use that. – ErikR Nov 30 '14 at 21:04
  • Yes, I can use that. However, there would still be the bit of code `main = run`, that would be left untested. I know it can be argued that this is just a tiny bit of code and so testing it is pointless, but I think it also can be argued that it is the most crucial bit of code in the entire program! – Michal Charemza Nov 30 '14 at 21:09