1

I have a program that takes a user input from getLine then validates that it is all numbers. If it passes it runs a function of String -> String and prints the result to screen. If not it repeats the getLine.

module Main where

import Control.Monad.Loops (untilJust)
import Data.Char           (isDigit)

main = do
  let validateInput s = if all isDigit s then Just s else Nothing
  putStrLn =<< myFunc <$> untilJust (validateInput <$> (putStr "Number : " >> getLine))

myFunc = id -- to do

How do I test the this main function with something like Hspec to check that it does the right thing with a number input vs other inputs (letters, empty etc)

ie

test1 rejects a non-numeric input of "abc"
test2 returns 123 as 123
duplode
  • 33,731
  • 7
  • 79
  • 150
matt
  • 1,817
  • 14
  • 35

1 Answers1

2

Since you want to test the logic rather than the user interaction, I'd suggest that you simply factor out the input validation.

SwiftsNamesake
  • 1,540
  • 2
  • 11
  • 25
  • well, I think I want a bit more than just the logic. I essentially want to test it from the end point ie I want to test my entire programs functionality against a set of possible inputs. I would indeed test `myFunc` and test `validateInput` ... however I want to test everything as a whole... if that is possible at all. – matt Jul 29 '17 at 03:19
  • I answered based on the output example you provided. I'm not sure if you can test IO easily with HSpec, but if you want to test the 'plumbing', I suppose you could use a different monad that emulates IO, feeding data and recording output. Maybe something like the State monad. – SwiftsNamesake Jul 29 '17 at 03:34
  • @matthias [This answer](https://stackoverflow.com/a/41699338/2670439) seems to suggest a similar approach. – SwiftsNamesake Jul 29 '17 at 05:08
  • @matthias Does that answer your question in full? – SwiftsNamesake Jul 29 '17 at 11:32
  • 1
    sorry, have not been at a computer all day. I think your question answers enough and points me in the right direction. Thanks – matt Jul 29 '17 at 23:13