{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TypeApplications #-} module Test.Cardano.Base.IP (tests) where import Cardano.Base.IP import Control.Exception (evaluate) import Data.Aeson (Result (..), fromJSON, toJSON) import Data.Aeson.QQ (aesonQQ) import Test.Hspec isError :: Result a -> Bool isError :: forall a. Result a -> Bool isError (Error String _) = Bool True isError Result a _ = Bool False tests :: Spec tests :: Spec tests = String -> Spec -> Spec forall a. HasCallStack => String -> SpecWith a -> SpecWith a describe String "IP" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do String -> Spec -> Spec forall a. HasCallStack => String -> SpecWith a -> SpecWith a describe String "IPv4" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Show instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do IPv4 -> String forall a. Show a => a -> String show ([Int] -> IPv4 toIPv4 [Int 192, Int 168, Int 1, Int 1]) String -> String -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` String "\"192.168.1.1\"" IPv4 -> String forall a. Show a => a -> String show ([Int] -> IPv4 toIPv4 [Int 0, Int 0, Int 0, Int 0]) String -> String -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` String "\"0.0.0.0\"" String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Read instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do (String -> IPv4 forall a. Read a => String -> a read String "\"192.168.1.1\"" :: IPv4) IPv4 -> IPv4 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv4 toIPv4 [Int 192, Int 168, Int 1, Int 1] (String -> IPv4 forall a. Read a => String -> a read String "\"0.0.0.0\"" :: IPv4) IPv4 -> IPv4 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv4 toIPv4 [Int 0, Int 0, Int 0, Int 0] String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Read fails on invalid input" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do IPv4 -> IO IPv4 forall a. a -> IO a evaluate (String -> IPv4 forall a. Read a => String -> a read String "\"invalid\"" :: IPv4) IO IPv4 -> Selector SomeException -> IO () forall e a. (HasCallStack, Exception e) => IO a -> Selector e -> IO () `shouldThrow` Selector SomeException anyException IPv4 -> IO IPv4 forall a. a -> IO a evaluate (String -> IPv4 forall a. Read a => String -> a read String "\"256.0.0.1\"" :: IPv4) IO IPv4 -> Selector SomeException -> IO () forall e a. (HasCallStack, Exception e) => IO a -> Selector e -> IO () `shouldThrow` Selector SomeException anyException String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Show/Read roundtrip" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do String -> IPv4 forall a. Read a => String -> a read (IPv4 -> String forall a. Show a => a -> String show ([Int] -> IPv4 toIPv4 [Int 192, Int 168, Int 1, Int 1])) IPv4 -> IPv4 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv4 toIPv4 [Int 192, Int 168, Int 1, Int 1] String -> IPv4 forall a. Read a => String -> a read (IPv4 -> String forall a. Show a => a -> String show ([Int] -> IPv4 toIPv4 [Int 0, Int 0, Int 0, Int 0])) IPv4 -> IPv4 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv4 toIPv4 [Int 0, Int 0, Int 0, Int 0] String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "ToJSON instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do IPv4 -> Value forall a. ToJSON a => a -> Value toJSON ([Int] -> IPv4 toIPv4 [Int 192, Int 168, Int 1, Int 1]) Value -> Value -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [aesonQQ| "192.168.1.1" |] IPv4 -> Value forall a. ToJSON a => a -> Value toJSON ([Int] -> IPv4 toIPv4 [Int 0, Int 0, Int 0, Int 0]) Value -> Value -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [aesonQQ| "0.0.0.0" |] String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "FromJSON instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do Value -> Result IPv4 forall a. FromJSON a => Value -> Result a fromJSON [aesonQQ| "192.168.1.1" |] Result IPv4 -> Result IPv4 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` IPv4 -> Result IPv4 forall a. a -> Result a forall (f :: * -> *) a. Applicative f => a -> f a pure ([Int] -> IPv4 toIPv4 [Int 192, Int 168, Int 1, Int 1]) Value -> Result IPv4 forall a. FromJSON a => Value -> Result a fromJSON [aesonQQ| "invalid" |] Result IPv4 -> (Result IPv4 -> Bool) -> IO () forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO () `shouldSatisfy` (forall a. Result a -> Bool isError @IPv4) Value -> Result IPv4 forall a. FromJSON a => Value -> Result a fromJSON [aesonQQ| 123 |] Result IPv4 -> (Result IPv4 -> Bool) -> IO () forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO () `shouldSatisfy` (forall a. Result a -> Bool isError @IPv4) String -> Spec -> Spec forall a. HasCallStack => String -> SpecWith a -> SpecWith a describe String "IPv6" (Spec -> Spec) -> Spec -> Spec forall a b. (a -> b) -> a -> b $ do String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Show instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do IPv6 -> String forall a. Show a => a -> String show ([Int] -> IPv6 toIPv6 [Int 0x2001, Int 0xdb8, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1]) String -> String -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` String "\"2001:db8::1\"" IPv6 -> String forall a. Show a => a -> String show ([Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0]) String -> String -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` String "\"::\"" IPv6 -> String forall a. Show a => a -> String show ([Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1]) String -> String -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` String "\"::1\"" String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Read instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do (String -> IPv6 forall a. Read a => String -> a read String "\"2001:db8::1\"" :: IPv6) IPv6 -> IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv6 toIPv6 [Int 0x2001, Int 0xdb8, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1] (String -> IPv6 forall a. Read a => String -> a read String "\"::\"" :: IPv6) IPv6 -> IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0] (String -> IPv6 forall a. Read a => String -> a read String "\"::1\"" :: IPv6) IPv6 -> IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1] String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Read fails on invalid input" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do IPv6 -> IO IPv6 forall a. a -> IO a evaluate (String -> IPv6 forall a. Read a => String -> a read String "\"invalid\"" :: IPv6) IO IPv6 -> Selector SomeException -> IO () forall e a. (HasCallStack, Exception e) => IO a -> Selector e -> IO () `shouldThrow` Selector SomeException anyException IPv6 -> IO IPv6 forall a. a -> IO a evaluate (String -> IPv6 forall a. Read a => String -> a read String "\"gggg::1\"" :: IPv6) IO IPv6 -> Selector SomeException -> IO () forall e a. (HasCallStack, Exception e) => IO a -> Selector e -> IO () `shouldThrow` Selector SomeException anyException String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "Show/Read roundtrip" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do String -> IPv6 forall a. Read a => String -> a read (IPv6 -> String forall a. Show a => a -> String show ([Int] -> IPv6 toIPv6 [Int 0x2001, Int 0xdb8, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1])) IPv6 -> IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv6 toIPv6 [Int 0x2001, Int 0xdb8, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1] String -> IPv6 forall a. Read a => String -> a read (IPv6 -> String forall a. Show a => a -> String show ([Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0])) IPv6 -> IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0] String -> IPv6 forall a. Read a => String -> a read (IPv6 -> String forall a. Show a => a -> String show ([Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1])) IPv6 -> IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1] String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "ToJSON instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do IPv6 -> Value forall a. ToJSON a => a -> Value toJSON ([Int] -> IPv6 toIPv6 [Int 0x2001, Int 0xdb8, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1]) Value -> Value -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [aesonQQ| "2001:db8::1" |] IPv6 -> Value forall a. ToJSON a => a -> Value toJSON ([Int] -> IPv6 toIPv6 [Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0, Int 0]) Value -> Value -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` [aesonQQ| "::" |] String -> IO () -> SpecWith (Arg (IO ())) forall a. (HasCallStack, Example a) => String -> a -> SpecWith (Arg a) it String "FromJSON instance" (IO () -> SpecWith (Arg (IO ()))) -> IO () -> SpecWith (Arg (IO ())) forall a b. (a -> b) -> a -> b $ do Value -> Result IPv6 forall a. FromJSON a => Value -> Result a fromJSON [aesonQQ| "2001:db8::1" |] Result IPv6 -> Result IPv6 -> IO () forall a. (HasCallStack, Show a, Eq a) => a -> a -> IO () `shouldBe` IPv6 -> Result IPv6 forall a. a -> Result a forall (f :: * -> *) a. Applicative f => a -> f a pure ([Int] -> IPv6 toIPv6 [Int 0x2001, Int 0xdb8, Int 0, Int 0, Int 0, Int 0, Int 0, Int 1]) Value -> Result IPv6 forall a. FromJSON a => Value -> Result a fromJSON [aesonQQ| "invalid" |] Result IPv6 -> (Result IPv6 -> Bool) -> IO () forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO () `shouldSatisfy` (forall a. Result a -> Bool isError @IPv6) Value -> Result IPv6 forall a. FromJSON a => Value -> Result a fromJSON [aesonQQ| 123 |] Result IPv6 -> (Result IPv6 -> Bool) -> IO () forall a. (HasCallStack, Show a) => a -> (a -> Bool) -> IO () `shouldSatisfy` (forall a. Result a -> Bool isError @IPv6)