packages feed

salak-0.2.7: test/Spec.hs

{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

import           Control.Monad.Reader
import           Control.Monad.Writer
import           Data.Either
import           Data.List            (intercalate)
import           Data.Menshen
import           Data.Text            (Text, pack, unpack)
import           GHC.Generics
import           Salak
import           Salak.Prop
import           Salak.Types
import           Salak.Types.Selector
import           Salak.Types.Source
import           Test.Hspec
import           Test.QuickCheck

main = hspec spec

spec :: Spec
spec = do
  describe "Salak.Types" specProperty

newtype SKey = SKey { unKey :: Text } deriving Show

instance Arbitrary SKey where
  arbitrary = do
    key <- choose (1,20)
    vs  <- vectorOf key $ do
      k <- choose (1,20)
      v <- vectorOf k $ choose ('a','z')
      b <- choose (0,10) :: Gen Int
      if b > 0 then return v else do
        x <- choose (0,10) :: Gen Int
        return (v ++ "[" ++ show x ++ "]")
    return (SKey $ pack $ intercalate "." vs)

data Conf = Conf
  { name :: String
  , age  :: Int
  , male :: Bool
  , det  :: SubConf
  } deriving (Eq, Show, Generic)

data SubConf = SubConf
  { hello :: String } deriving (Eq, Show, Generic)

instance FromProp SubConf where
  fromProp = SubConf <$> "hello" .?= "yyy" ? pattern "[a-z]{3,16}"

instance FromProp Conf

specProperty = do
  context "selectors" $ do
    it "normal" $ do
      selectors ""         `shouldBe` Right []
      selectors "."        `shouldBe` Right []
      selectors ".."       `shouldBe` Right []
      selectors "xx"       `shouldBe` Right [SStr "xx"]
      selectors "xx[0]"    `shouldBe` Right [SStr "xx", SNum 0]
      selectors "xx.yy"    `shouldBe` Right [SStr "xx", SStr "yy"]
      selectors "xx[0][1]" `shouldBe` Right [SStr "xx", SNum 0, SNum 1]
      toKey (reverse $ SStr "x" : (SNum <$> [0..9])) `shouldBe` "x[0][1][2][3][4][5][6][7][8][9]"
    it "QuickCheck" $ do
      quickCheck $ \s -> let s' = unKey s in (toKey . reverse <$> selectors s') `shouldBe` Right (unpack s')
  context "source" $ do
    it "normal" $ do
      sizeSource emptySource `shouldBe` 0
    it "normal - 2" $ do
      let (s1,e1) = runWriter $ insert "hello" (VStr 0 "world") emptySource
      sizeSource s1       `shouldBe` 1
      length e1           `shouldBe` 0
    it "normal - 3" $ do
      let (s2,e2) = runWriter $ insert "1"     (VStr 0 "world") emptySource
      sizeSource s2       `shouldBe` 1
      length e2           `shouldBe` 00
    it "normal - 4" $ do
      let (s3,e3) = runWriter $ insert "a.b"   (VStr 0 "world") emptySource
      print s3
      sizeSource s3       `shouldBe` 1
      length e3           `shouldBe` 0
  context "source - merge" $ do
    let s  = fst $ runWriter $ insert "hello" (VStr 0 "world") emptySource
        s1 = fst $ runWriter $ insert "hello" (VStr 0 "xxxxx") emptySource
    it "merge - del" $ do
      let (s2,e2) = runWriter $ replace 0 emptySource s
      s2 `shouldBe` emptySource
      e2 `shouldBe` ["#0 Del hello"]
    it "merge - mod" $ do
      let (s3,e3) = runWriter $ replace 0 s1 s
      e3 `shouldBe` ["#0 Mod hello"]
      s3 `shouldBe` s1
    it "merge - add" $ do
      let (s4,e4) = runWriter $ replace 0 s emptySource
      e4 `shouldBe` ["#0 Add hello"]
      s4 `shouldBe` s
    it "merge - unchange" $ do
      let (s5,e5) = runWriter $ replace 0 s s
      e5 `shouldBe` []
      s5 `shouldBe` s
  context "Generic" $ do
    it "conf" $ do
      sp <- runSourcePackT $ loadMock
        [ ("name", "Daniel")
        , ("age", "18")
        , ("male", "yes")
        ]
      errs sp `shouldBe` []
      let a = search "" sp :: Either String Conf
      print a
      isRight a `shouldBe` True