From: Michael Orlitzky Date: Sun, 18 Aug 2013 20:34:37 +0000 (-0400) Subject: Add some more tests; minor code cleanup. X-Git-Tag: 0.0.4~7 X-Git-Url: http://gitweb.michael.orlitzky.com/?p=hath.git;a=commitdiff_plain;h=18a81546e7c4ad10574918efb08b2e104e911d73 Add some more tests; minor code cleanup. --- diff --git a/hath.cabal b/hath.cabal index f495f7b..b11ea39 100644 --- a/hath.cabal +++ b/hath.cabal @@ -62,7 +62,7 @@ description: executable hath build-depends: - base == 4.*, + base >= 4.6.0, bytestring == 0.10.*, dns == 0.3.*, HUnit == 1.2.*, @@ -119,7 +119,7 @@ test-suite testsuite hs-source-dirs: src test main-is: TestSuite.hs build-depends: - base == 4.*, + base >= 4.6.0, bytestring == 0.10.*, dns == 0.3.*, HUnit == 1.2.*, diff --git a/src/Cidr.hs b/src/Cidr.hs index e23ae6c..b5b3f74 100644 --- a/src/Cidr.hs +++ b/src/Cidr.hs @@ -30,6 +30,7 @@ import Test.Framework (Test, testGroup) import Test.Framework.Providers.HUnit (testCase) import Test.Framework.Providers.QuickCheck2 (testProperty) import Test.QuickCheck (Arbitrary(..), Gen, Property, (==>)) +import Text.Read (readMaybe) import qualified Bit as B import IPv4Address @@ -78,7 +79,7 @@ maskbits_from_cidr_string s -- of its octets (as Ints). octets_from_cidr_string :: String -> [Octet] octets_from_cidr_string s = - mapMaybe octet_from_string (take 4 (splitOneOf "./" s)) + mapMaybe readMaybe (take 4 (splitOneOf "./" s)) -- | Return Nothing if we can't parse both maskbits and octets from diff --git a/src/ExitCodes.hs b/src/ExitCodes.hs index 4257191..ef5d73f 100644 --- a/src/ExitCodes.hs +++ b/src/ExitCodes.hs @@ -1,5 +1,8 @@ -- | Some exit codes, used in the ExitFailure constructor. -module ExitCodes +module ExitCodes ( + exit_args_parse_failed, + exit_invalid_cidr + ) where -- | One of the CIDRs is invalid (malformed, not a CIDR at all, etc). diff --git a/src/IPv4Address.hs b/src/IPv4Address.hs index 7c44367..15e6966 100644 --- a/src/IPv4Address.hs +++ b/src/IPv4Address.hs @@ -180,10 +180,10 @@ ipv4address_to_int :: IPv4Address -> Int ipv4address_to_int addr = (shifted_oct1) + (shifted_oct2) + (shifted_oct3) + oct4 where - oct1 = octet_to_int (octet1 addr) - oct2 = octet_to_int (octet2 addr) - oct3 = octet_to_int (octet3 addr) - oct4 = octet_to_int (octet4 addr) + oct1 = fromEnum (octet1 addr) + oct2 = fromEnum (octet2 addr) + oct3 = fromEnum (octet3 addr) + oct4 = fromEnum (octet4 addr) shifted_oct1 = oct1 * 2^(24 :: Integer) shifted_oct2 = oct2 * 2^(16 :: Integer) @@ -346,7 +346,8 @@ ipv4address_tests = test_maxBound, test_minBound, test_most_sig_bit_different1, - test_most_sig_bit_different2 ] + test_most_sig_bit_different2, + test_to_enum ] ipv4address_properties :: Test ipv4address_properties = @@ -423,3 +424,10 @@ test_most_sig_bit_different2 = bit = most_sig_bit_different addr1 addr2 +test_to_enum :: Test +test_to_enum = + testCase desc $ assertEqual desc expected actual + where + desc = "192.168.0.0 in base-10 is 3232235520" + expected = mk_testaddr 192 168 0 0 + actual = toEnum 3232235520 diff --git a/src/Main.hs b/src/Main.hs index d8c7600..e57959e 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -30,8 +30,8 @@ import CommandLine (help_set, parse_mode) import DNS (Domain, lookup_ptrs) -import ExitCodes -import Octet +import ExitCodes ( exit_args_parse_failed, exit_invalid_cidr ) +import Octet () -- | A regular expression that matches a non-address character. @@ -63,14 +63,14 @@ cidr_to_regex cidr = range2 = numeric_range min2 max2 range3 = numeric_range min3 max3 range4 = numeric_range min4 max4 - min1 = octet_to_int (min_octet1 cidr) - min2 = octet_to_int (min_octet2 cidr) - min3 = octet_to_int (min_octet3 cidr) - min4 = octet_to_int (min_octet4 cidr) - max1 = octet_to_int (max_octet1 cidr) - max2 = octet_to_int (max_octet2 cidr) - max3 = octet_to_int (max_octet3 cidr) - max4 = octet_to_int (max_octet4 cidr) + min1 = fromEnum (min_octet1 cidr) + min2 = fromEnum (min_octet2 cidr) + min3 = fromEnum (min_octet3 cidr) + min4 = fromEnum (min_octet4 cidr) + max1 = fromEnum (max_octet1 cidr) + max2 = fromEnum (max_octet2 cidr) + max3 = fromEnum (max_octet3 cidr) + max4 = fromEnum (max_octet4 cidr) diff --git a/src/Octet.hs b/src/Octet.hs index 531d4d0..574edc4 100644 --- a/src/Octet.hs +++ b/src/Octet.hs @@ -1,13 +1,17 @@ -module Octet +module Octet ( + Octet(..), + octet_from_int, + octet_properties, + octet_tests, + ) where import Data.Maybe (fromJust) - import Test.HUnit (assertEqual) import Test.Framework (Test, testGroup) import Test.Framework.Providers.HUnit (testCase) - -import Test.QuickCheck (Arbitrary(..), Gen) +import Test.Framework.Providers.QuickCheck2 (testProperty) +import Test.QuickCheck (Arbitrary(..), Gen, Property, (==>)) import Bit as B import Maskable @@ -29,7 +33,7 @@ data Octet = instance Show Octet where - show oct = show (octet_to_int oct) + show oct = show (fromEnum oct) instance Arbitrary Octet where @@ -106,21 +110,19 @@ instance Enum Octet where -- maxBound), so the fromJust here doesn't introduce any additional -- badness. toEnum = fromJust . octet_from_int - fromEnum = octet_to_int --- | Convert each bit to its integer value, and multiply by the --- appropriate power of two. Sum them up, and we should get an integer --- between 0 and 255. -octet_to_int :: Octet -> Int -octet_to_int x = - 128 * (bit_to_int (b1 x)) + - 64 * (bit_to_int (b2 x)) + - 32 * (bit_to_int (b3 x)) + - 16 * (bit_to_int (b4 x)) + - 8 * (bit_to_int (b5 x)) + - 4 * (bit_to_int (b6 x)) + - 2 * (bit_to_int (b7 x)) + - 1 * (bit_to_int (b8 x)) + -- | Convert each bit to its integer value, and multiply by the + -- appropriate power of two. Sum them up, and we should get an integer + -- between 0 and 255. + fromEnum x = + 128 * (bit_to_int (b1 x)) + + 64 * (bit_to_int (b2 x)) + + 32 * (bit_to_int (b3 x)) + + 16 * (bit_to_int (b4 x)) + + 8 * (bit_to_int (b5 x)) + + 4 * (bit_to_int (b6 x)) + + 2 * (bit_to_int (b7 x)) + + 1 * (bit_to_int (b8 x)) @@ -139,13 +141,49 @@ octet_from_int x a8 = if ((x `mod` 2) == 1) then B.One else B.Zero -octet_from_string :: String -> Maybe Octet -octet_from_string s = - case (reads s :: [(Int, String)]) of - [] -> Nothing - x:_ -> octet_from_int (fst x) +instance Read Octet where + readsPrec _ = \s -> + case (reads s :: [(Int, String)]) of + [] -> [] + (x,leftover):_ -> case (octet_from_int x) of + Nothing -> [] + Just oct -> [(oct, leftover)] + +-- Test lists. +octet_tests :: Test +octet_tests = + testGroup "Octet Tests" [ + test_octet_from_int1, + test_octet_mask1, + test_octet_mask2 ] +octet_properties :: Test +octet_properties = + testGroup + "Octet Properties " + [ testProperty + "fromEnum/toEnum are inverses" + prop_from_enum_to_enum_inverses, + testProperty + "read/show are inverses" + prop_read_show_inverses ] + +-- QuickCheck properties +prop_from_enum_to_enum_inverses :: Int -> Property +prop_from_enum_to_enum_inverses x = + (0 <= x) && (x <= 255) ==> + fromEnum (toEnum x :: Octet) == x + +prop_read_show_inverses :: Int -> Property +prop_read_show_inverses x = + (0 <= x) && (x <= 255) ==> x' == x + where + oct :: Octet + oct = read $ show x + + x' :: Int + x' = read $ show oct -- HUnit Tests test_octet_from_int1 :: Test @@ -174,11 +212,3 @@ test_octet_mask2 = desc = "The network bits of 255/1 should equal 128" oct1 = fromJust $ octet_from_int 255 oct2 = fromJust $ octet_from_int 128 - - -octet_tests :: Test -octet_tests = - testGroup "Octet Tests" [ - test_octet_from_int1, - test_octet_mask1, - test_octet_mask2 ] diff --git a/test/TestSuite.hs b/test/TestSuite.hs index 69bae3c..172bcfc 100644 --- a/test/TestSuite.hs +++ b/test/TestSuite.hs @@ -2,21 +2,26 @@ import Data.Monoid (mempty) import Test.Framework ( Test, - defaultMainWithOpts, - ) + defaultMainWithOpts ) import Test.Framework.Options import Test.Framework.Runners.Options -import Cidr (cidr_properties, cidr_tests) - -import IPv4Address (ipv4address_properties, ipv4address_tests) -import Octet (octet_tests) +import Cidr ( + cidr_properties, + cidr_tests ) +import IPv4Address ( + ipv4address_properties, + ipv4address_tests ) +import Octet ( + octet_properties, + octet_tests ) tests :: [Test.Framework.Test] tests = [ cidr_properties, cidr_tests, ipv4address_properties, ipv4address_tests, + octet_properties, octet_tests ] main :: IO ()