{-# OPTIONS_GHC -fno-warn-type-defaults #-} {-# LANGUAGE RecordWildCards #-} import Data.Foldable (for_) import Test.Hspec (Spec, describe, it, shouldBe) import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith) import Hamming (distance) main :: IO () main = hspecWith defaultConfig {configFastFail = True} specs specs :: Spec specs = describe "distance" $ for_ cases test where test Case{..} = it description assertion where assertion = expression `shouldBe` fromIntegral <$> expected expression = distance strand1 strand2 data Case = Case { description :: String , strand1 :: String , strand2 :: String , expected :: Maybe Integer } cases :: [Case] cases = [ Case { description = "identical strands" , strand1 = "A" , strand2 = "A" , expected = Just 0 } , Case { description = "long identical strands" , strand1 = "GGACTGA" , strand2 = "GGACTGA" , expected = Just 0 } , Case { description = "complete distance in single nucleotide strands" , strand1 = "A" , strand2 = "G" , expected = Just 1 } , Case { description = "complete distance in small strands" , strand1 = "AG" , strand2 = "CT" , expected = Just 2 } , Case { description = "small distance in small strands" , strand1 = "AT" , strand2 = "CT" , expected = Just 1 } , Case { description = "small distance" , strand1 = "GGACG" , strand2 = "GGTCG" , expected = Just 1 } , Case { description = "small distance in long strands" , strand1 = "ACCAGGG" , strand2 = "ACTATGG" , expected = Just 2 } , Case { description = "non-unique character in first strand" , strand1 = "AGA" , strand2 = "AGG" , expected = Just 1 } , Case { description = "non-unique character in second strand" , strand1 = "AGG" , strand2 = "AGA" , expected = Just 1 } , Case { description = "same nucleotides in different positions" , strand1 = "TAG" , strand2 = "GAT" , expected = Just 2 } , Case { description = "large distance" , strand1 = "GATACA" , strand2 = "GCATAA" , expected = Just 4 } , Case { description = "large distance in off-by-one strand" , strand1 = "GGACGGATTCTG" , strand2 = "AGGACGGATTCT" , expected = Just 9 } , Case { description = "empty strands" , strand1 = "" , strand2 = "" , expected = Just 0 } , Case { description = "disallow first strand longer" , strand1 = "AATG" , strand2 = "AAA" , expected = Nothing } , Case { description = "disallow second strand longer" , strand1 = "ATA" , strand2 = "AGTG" , expected = Nothing } ]