packages feed

ble-0.1.0.0: test/Bluetooth/TypesSpec.hs

{-# OPTIONS_GHC -fno-warn-orphans #-}
module Bluetooth.TypesSpec (spec) where

import Data.IORef
import Data.Proxy                (Proxy (Proxy))
import DBus
import System.IO.Unsafe          (unsafePerformIO)
import Test.Hspec
import Test.QuickCheck
import Test.QuickCheck.Instances ()

import qualified Data.Text as T

import Bluetooth.Internal.Types

spec :: Spec
spec = do
  uuidSpec
  parentPathSpec
  chrPropPairsSpec

uuidSpec :: Spec
uuidSpec = describe "UUID" $ do

  context "fromString" $ do

    it "works for full UUIDs" $ do
      show ("636e8de5-c57b-4069-8c59-bb72e1ad805e" :: UUID)
        `shouldBe` "UUID 636e8de5-c57b-4069-8c59-bb72e1ad805e"

    it "works for 32-bit UUIDs" $ do
      show ("636e8de5" :: UUID)
        `shouldBe` "UUID 636e8de5-0000-1000-8000-00805f9b34fb"

    it "throws an error for invalid UUIDs" $ do
      print ("boo" :: UUID) `shouldThrow` anyException

  context "Representable" $ do
    fromRepToRepInverse (Proxy :: Proxy UUID)

parentPathSpec :: Spec
parentPathSpec = describe "parentPath" $ do

  it "returns the path of the parent" $ do
    parentPath "/com/turingjump/service01/char10"
      `shouldBe` "/com/turingjump/service01"

chrPropPairsSpec :: Spec
chrPropPairsSpec = describe "chrPropPairs" $ do

  it "contains all constructors of CharacteristicProperty" $ do
    all (`elem` (fst <$> chrPropPairs)) [minBound..maxBound] `shouldBe` True

-- * Utils

fromRepToRepInverse
  :: forall proxy a. (Eq a, Arbitrary a, Representable a, Show a)
  => proxy a -> Spec
fromRepToRepInverse _
  = it "has fromRep as a left inverse of toRep" $ property $ \val -> do
      fromRep (toRep (val :: a)) `shouldBe` Just val

-- * Instances

instance Arbitrary UUID where
  arbitrary = choose ("00000000-0000-0000-0000-000000000000"
                     ,"FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"
                     )

instance Arbitrary Application where
  arbitrary = Application <$> arbitrary <*> arbitrary

instance Arbitrary ObjectPath where
  arbitrary = objectPath . T.pack <$> arbitrary

instance Arbitrary Service where
  arbitrary = Service <$> arbitrary <*> arbitrary

instance (CoArbitrary a, Arbitrary a)
  => Arbitrary (Characteristic a) where
  arbitrary = Characteristic
    <$> arbitrary
    <*> arbitrary
    <*> (fmap return <$> arbitrary)
    <*> (fmap (fmap return) <$> arbitrary)
    <*> genIORef
    where
      genIORef = do
        m <- arbitrary
        if m then Just . unsafePerformIO . newIORef <$> arbitrary
             else return Nothing

instance Arbitrary CharacteristicProperty where
  arbitrary = elements [minBound..maxBound]