persistent-audit-0.1.0.2: tests/Database/Persist/Audit/ParserSpec.hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Database.Persist.Audit.ParserSpec ( main
, spec) where
import Data.Attoparsec.Text
import Data.Either
import Database.Persist.Audit.Parser
import Database.Persist.Audit.Parser.Types
import Database.Persist.Audit.Types
import Test.Hspec ( Spec
, describe
, hspec
, it
, shouldBe
, shouldMatchList)
spec :: Spec
spec = do
describe "Haskell Function Name Parser" $ do
-- should pass
it "Should parse function names starting with an underscore" $ do
let parseResult = parseOnly haskellFunctionName "_get"
parseResult `shouldBe` (Right "_get")
it "Should parse function names starting with a lowercase letter" $ do
let parseResult = parseOnly haskellFunctionName "get"
parseResult `shouldBe` (Right "get")
it "Should parse function names with an numbers" $ do
let parseResult = parseOnly haskellFunctionName "get1"
parseResult `shouldBe` (Right "get1")
it "Should parse function names and ignore the trailing whitespace" $ do
let parseResult = parseOnly haskellFunctionName "get "
parseResult `shouldBe` (Right "get")
it "Should parse function names, ignore the trailing whitespace, and the things that follow the whitespace" $ do
let parseResult = parseOnly haskellFunctionName "get anotherthing"
parseResult `shouldBe` (Right "get")
-- should fail
it "Should not parse inputs that start with whitespace" $ do
let parseResult = parseOnly haskellFunctionName " _get"
isLeft parseResult `shouldBe` True
it "Should not parse function names starting with an uppercase letter" $ do
let parseResult = parseOnly haskellFunctionName "Get"
isLeft parseResult `shouldBe` True
it "Should not parse function names starting with a number" $ do
let parseResult = parseOnly haskellFunctionName "1get"
isLeft parseResult `shouldBe` True
it "Should not parse function names with symbols other than letters, numbers and underscores" $ do
let parseResults = [ parseOnly haskellFunctionName "get!"
, parseOnly haskellFunctionName "get$"
, parseOnly haskellFunctionName "get+"
, parseOnly haskellFunctionName "get="
, parseOnly haskellFunctionName "get-"
]
(rights parseResults) `shouldMatchList` []
describe "Haskell Type Name Parser" $ do
-- should pass
it "Should parse type names starting with an uppercase letter" $ do
let parseResult = parseOnly haskellTypeName "Person"
parseResult `shouldBe` (Right "Person")
it "Should parse type names starting with an uppercase letter" $ do
let parseResult = parseOnly haskellTypeName "Person"
parseResult `shouldBe` (Right "Person")
it "Should parse strict type names" $ do
let parseResult = parseOnly haskellTypeName "!Get"
parseResult `shouldBe` (Right "Get")
-- parseResult `shouldBe` (Right "!Get")
it "Should parse lazy type names" $ do
let parseResult = parseOnly haskellTypeName "~Get"
parseResult `shouldBe` (Right "Get")
-- should fail
it "Should not parse type names starting with a lowercase letter" $ do
let parseResult = parseOnly haskellTypeName "person"
isLeft parseResult `shouldBe` True
it "Should not parse type names with symbols other than letters, numbers and underscores" $ do
let parseResults = [ parseOnly haskellTypeName "Get!"
, parseOnly haskellTypeName "Get$"
, parseOnly haskellTypeName "Get+"
, parseOnly haskellTypeName "Get="
, parseOnly haskellTypeName "Get-"
]
(rights parseResults) `shouldMatchList` []
describe "parseEntityPrimary" $ do
it "should parse" $ do
let parseResult = parseOnly parseEntityPrimary " Primary name age"
parseResult `shouldBe` (Right (EntityPrimary ["name","age"]))
describe "parseEntityForeign" $ do
it "should parse" $ do
let parseResult = parseOnly parseEntityForeign " Foreign Tree fkparent parent"
parseResult `shouldBe` (Right (EntityForeign "Tree" ["fkparent","parent"]))
describe "parseMigrationOnlyAndSafeToRemove" $ do
it "Should parse MigrationOnly" $ do
let parseResult = parseOnly (parseMigrationOnlyAndSafeToRemove []) " MigrationOnly"
parseResult `shouldBe` (Right [MigrationOnly])
it "Should parse SafeToRemove" $ do
let parseResult = parseOnly (parseMigrationOnlyAndSafeToRemove []) " SafeToRemove"
parseResult `shouldBe` (Right [SafeToRemove])
it "Should parse empty space" $ do
let parseResult = parseOnly (parseMigrationOnlyAndSafeToRemove []) " "
parseResult `shouldBe` (Right [])
it "Should parse MigrationOnly and SafeToRemove" $ do
let parseResult = parseOnly (parseMigrationOnlyAndSafeToRemove []) " MigrationOnly SafeToRemove"
parseResult `shouldBe` (Right [MigrationOnly,SafeToRemove])
it "Should parse SafeToRemove and MigrationOnly" $ do
let parseResult = parseOnly (parseMigrationOnlyAndSafeToRemove []) " SafeToRemove MigrationOnly"
parseResult `shouldBe` (Right [SafeToRemove,MigrationOnly])
describe "parseEntityFieldLastItem" $ do
it "Should parse a default assignment" $ do
let parseResult = parseOnly (parseEntityFieldLastItem []) " default = Nothing"
parseResult `shouldBe` (Right [(FieldDefault "Nothing")])
it "Should parse an sql row assignment" $ do
let parseResult = parseOnly (parseEntityFieldLastItem []) " sql=person"
parseResult `shouldBe` (Right [(FieldSqlRow "person")])
it "Should parse an sql type assignment" $ do
let parseResult = parseOnly (parseEntityFieldLastItem []) " sqltype=date"
parseResult `shouldBe` (Right [(FieldSqlType "date")])
it "Should parse an maxlen assignment" $ do
let parseResult = parseOnly (parseEntityFieldLastItem []) " maxlen=15"
parseResult `shouldBe` (Right [(FieldMaxLen 15)])
it "Should parse mulitple items" $ do
let parseResult = parseOnly (parseEntityFieldLastItem []) " default = Nothing maxlen=15"
parseResult `shouldBe` (Right [(FieldDefault "Nothing"), (FieldMaxLen 15)])
it "Should parse mulitple items" $ do
let parseResult = parseOnly (parseEntityFieldLastItem []) " default = Nothing maxlen=15 sqltype=date sql=person"
parseResult `shouldBe` (Right [(FieldDefault "Nothing"), (FieldMaxLen 15),(FieldSqlType "date"), (FieldSqlRow "person")])
describe "parseEntity" $ do
it "parses Entity with only a table name" $ do
let parseResult = parseOnly (parseEntity) "Person"
parseResult `shouldBe` (Right (Entity "Person" False Nothing []))
it "parses Entity with table name and derive json" $ do
let parseResult = parseOnly (parseEntity) "Person json"
parseResult `shouldBe` (Right (Entity "Person" True Nothing []))
it "parses Entity with table name and sql table set to person" $ do
let parseResult = parseOnly (parseEntity) "Person sql = person"
parseResult `shouldBe` (Right (Entity "Person" False (Just "person") []))
it "parses Entity with table name, derive json, and table set to person" $ do
let parseResult = parseOnly (parseEntity) "Person json sql= person"
parseResult `shouldBe` (Right (Entity "Person" True (Just "person") []))
it "parses Entity with table name and one field" $ do
let parseResult = parseOnly (parseEntity) "Person\n name Text"
parseResult `shouldBe` (Right (Entity "Person" False Nothing [(EntityChildEntityField $ EntityField "name" (EntityFieldType "Text" Strict False False) False False Nothing Nothing Nothing Nothing)]))
it "parses Entity with a table name, multiple fields, Unique, Foreign and deriving" $ do
let parseResult = parseOnly (parseEntity) "Person\n name Text\n phoneNumber Int Maybe\n friends [PersonId]\n UniquePerson name\n deriving Eq Read Show\n Primary name age"
parseResult `shouldBe` (Right (Entity "Person" False Nothing [(EntityChildEntityField $ EntityField "name" (EntityFieldType "Text" Strict False False) False False Nothing Nothing Nothing Nothing)
,(EntityChildEntityField $ EntityField "phoneNumber" (EntityFieldType "Int" Strict False True) False False Nothing Nothing Nothing Nothing)
,(EntityChildEntityField $ EntityField "friends" (EntityFieldType "PersonId" Strict True False) False False Nothing Nothing Nothing Nothing)
,(EntityChildEntityUnique $ EntityUnique "UniquePerson" ["name"])
,(EntityChildEntityDerive $ EntityDerive ["Eq","Read","Show"])
,(EntityChildEntityPrimary $ EntityPrimary ["name","age"])]))
describe "parseEntityField" $ do
it "Should parse a well formed entity field" $ do
let sampleEntityField = " ident Text"
let eft = EntityFieldType "Text" Strict False False
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
it "Should parse a well formed entity field with list type" $ do
let sampleEntityField = " ident [Text]"
let eft = EntityFieldType "Text" Strict True False
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
it "Should parse a well formed entity field with maybe type" $ do
let sampleEntityField = " ident Text Maybe"
let eft = EntityFieldType "Text" Strict False True
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
it "Should parse a well formed entity field with maybe list type" $ do
let sampleEntityField = " ident [Text] Maybe"
let eft = EntityFieldType "Text" Strict True True
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
it "Should parse an entity field with explicit strict type" $ do
let sampleEntityField = " ident !Text"
let eft = EntityFieldType "Text" ExplicitStrict False False
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
it "Should parse an entity field with a lazy type" $ do
let sampleEntityField = " ident ~Text"
let eft = EntityFieldType "Text" Lazy False False
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
it "Should parse an entity field with a list of lazy types" $ do
let sampleEntityField = " ident [~Text]"
let eft = EntityFieldType "Text" Lazy True False
let ef = EntityField "ident" eft False False Nothing Nothing Nothing Nothing
let parseResult = parseOnly parseEntityField sampleEntityField
parseResult `shouldBe` (Right ef)
main :: IO ()
main = hspec spec