My Main.hs
file takes in commandline arguments:
module Main (toLowerStr, Result(..), grade, main) where
...
grade :: [String] -> String -> String -> (Bool, Result, [Highlight])
grade dictWords correctAnswer studentAnswer =
...
...
main :: IO ()
main = do
args <- getArgs
dict <- readFile $ args !! 0
...
Which works fine, except when I try to test. My testing file is
module Testing where
import Main
import Test.Hspec
main :: IO ()
main = do
dict <- readFile "dict.txt"
let dictWords = map toLowerStr $ lines dict
hspec $ do
describe "Validate passing answers" $ do
it "Match should be verified exactly" $ do
grade dictWords "house" "house"
`shouldBe` (True, Perfect, [])
Yet when I run cabal test
it still gives me
Preprocessing test suite 'tests' for grade-0.1.0.0...
[2 of 2] Compiling Testing ( src/HSpecTests.hs, dist/build/tests/tests-tmp/Testing.o )
Linking dist/build/tests/tests ...
Running 1 test suites...
Test suite tests: RUNNING...
tests: Prelude.(!!): index too large
Test suite tests: FAIL
I'm pretty sure it's failing because of the calls to args
in Main.main
, because the executable itself works fine, and I don't see !!
being used anywhere else.
How do I get tests to run?
EDIT: Used pattern matching in Main.hs
:
main :: IO ()
main = do
[filename, correctString, studentString] <- getArgs
...
and the error is now
[1 of 2] Compiling Main ( src/Main.hs, dist/build/tests/tests-tmp/Main.o )
Linking dist/build/tests/tests ...
Running 1 test suites...
Test suite tests: RUNNING...
tests: user error (Pattern match failure in do expression at src/Main.hs:141:9-48)
Test suite tests: FAIL
EDIT 2: My entire grade.cabal
file
-- Initial grade.cabal generated by cabal init. For further documentation,
-- see http://haskell.org/cabal/users-guide/
name: grade
version: 0.1.0.0
-- synopsis:
-- description:
license-file: LICENSE
author: Amos Ng <amosng@cmu.edu>
maintainer: Amos Ng <amosng@cmu.edu>
-- copyright:
category: Language
build-type: Simple
cabal-version: >=1.8
executable grade
main-is: Main.hs
-- other-modules:
build-depends: base, split ==0.2.*
hs-source-dirs: src
test-suite tests
ghc-options: -Wall
type: exitcode-stdio-1.0
main-is: HSpecTests.hs
other-modules: Main
build-depends: base, split ==0.2.*, hspec ==1.11.*
hs-source-dirs: src
GHC will always use as the entry point the function named main out of the module named Main
. Since HSpecTests.hs
is the Testing
module, not the Main
module, its main
is completely ignored, instead favoring the main
from the Main
module. You should break your logic out of the Main
module, leaving the Main
module as a command-line stub. Then you’ll want to exclude that from the test build, and change module Testing
to module Main
in HSpecTests.hs
.