lorentz-0.1.0: test/Test/Doc.hs
-- | Tests on automatic documentation generation.
module Test.Doc
( test_General_doc_scan
, test_Dependencies_loops
, test_Cutting_all_except_doc
, test_fakeCoerce
) where
import qualified Data.Set as Set
import Fmt (build)
import Test.HUnit (assertBool, assertFailure, (@?=))
import Test.QuickCheck (total)
import Test.Tasty (TestTree)
import Test.Tasty.HUnit (testCase)
import Test.Tasty.QuickCheck (testProperty)
import Lorentz (( # ))
import qualified Lorentz as L
import Michelson.Doc
import Michelson.Typed
import Util.Named
-- General tests on contract doc scan
----------------------------------------------------------------------------
newtype MyType = MyType Integer
deriving stock (Generic)
deriving anyclass (IsoValue)
instance TypeHasDoc MyType where
typeDocMdDescription = ""
data MyGroup = MyGroup Text SubDoc
instance DocItem MyGroup where
type DocItemPosition MyGroup = 91232
docItemSectionName = Nothing
docItemToMarkdown lvl (MyGroup name subDoc) =
build name <> subDocToMarkdown lvl subDoc
test_General_doc_scan :: [TestTree]
test_General_doc_scan =
[ testCase "Type declaration is found" $
let contract = L.doc $ DType (Proxy @MyType)
doc = L.buildLorentzDoc contract
in case lookupDocBlockSection @DType $ cdDefinitions doc of
Just (toList -> ds) ->
sort ds @?= sort [DType (Proxy @MyType), DType (Proxy @Integer)]
Nothing ->
assertFailure "DTypes not found"
, testCase "Dependencies of polymorphic types are found" $
-- There once was a bug which caused, in the following scenario,
-- 'Integer' type to be found while 'Natural' to be not, doc items
-- discovery thought that ":!" has already been traversed and didn't
-- pick its dependencies the second time.
let contract = L.doc $ L.mkDEntryPointArgSimple @("a" :! Integer, "b" :! Natural)
doc = L.buildLorentzDoc contract
defs = cdDefinitionsSet doc
in do
assertBool "'Integer' declaration is present" $
Set.member (SomeDocDefinitionItem $ DType (Proxy @Integer)) defs
assertBool "'Natural' declaration is present" $
Set.member (SomeDocDefinitionItem $ DType (Proxy @Natural)) defs
, testCase "Doc group is handled correctly" $
let contract = L.docGroup (SomeDocItem . MyGroup "a") $
L.doc $ DDescription "a"
doc = L.buildLorentzDoc contract
contents = cdContents doc
in case lookupDocBlockSection contents of
Just (MyGroup "a" (SubDoc subcontents) :| []) ->
case lookupDocBlockSection subcontents of
Just (DDescription "a" :| []) ->
pass
_ -> assertFailure $ "Unexpected subcontents: " <> show subcontents
_ -> assertFailure $ "Unexpected contents: " <> show contents
]
-- Test on loops on dependency graph of doc items
----------------------------------------------------------------------------
-- | Type, documentation for which somehow depends on itself.
newtype MyLoopedType = MyLoopedType Integer
deriving stock (Generic)
deriving anyclass (IsoValue)
instance TypeHasDoc MyLoopedType where
typeDocDependencies _ = [SomeTypeWithDoc (Proxy @MyLoopedType)]
typeDocMdDescription = ""
newtype MyMutuallyDependentType1 = MyMutuallyDependentType1 Integer
deriving stock (Generic)
deriving anyclass (IsoValue)
newtype MyMutuallyDependentType2 = MyMutuallyDependentType2 Integer
deriving stock (Generic)
deriving anyclass (IsoValue)
instance TypeHasDoc MyMutuallyDependentType1 where
typeDocDependencies _ = [SomeTypeWithDoc (Proxy @MyMutuallyDependentType2)]
typeDocMdDescription = ""
instance TypeHasDoc MyMutuallyDependentType2 where
typeDocDependencies _ = [SomeTypeWithDoc (Proxy @MyMutuallyDependentType1)]
typeDocMdDescription = ""
test_Dependencies_loops :: [TestTree]
test_Dependencies_loops =
[ testProperty "Type depending on itself" $
let contract = L.doc $ DType (Proxy @MyLoopedType)
in total . contractDocToMarkdown $ L.buildLorentzDoc contract
, testProperty "Mutually dependent types" $
let contract = L.doc $ DType (Proxy @MyMutuallyDependentType1)
in total . contractDocToMarkdown $ L.buildLorentzDoc contract
]
-- Functions semantics
----------------------------------------------------------------------------
test_Cutting_all_except_doc :: [TestTree]
test_Cutting_all_except_doc =
[ testCase "Cleaning simple code" $
let contract =
L.doc (DDescription "a") #
L.push True #
L.if_ (L.contractName "aaa" $ L.doc $ DDescription "b") (L.sender # L.drop)
:: '[] L.:-> '[]
cutContract =
L.doc (DDescription "a") #
L.contractName "aaa" (L.doc $ DDescription "b")
in L.renderLorentzDoc (L.cutLorentzNonDoc contract)
@?=
L.renderLorentzDoc cutContract
, testCase "DocGroup is handled correctly" $
let contract =
L.docGroup (SomeDocItem . MyGroup "b") $
L.doc (DDescription "a") # L.nop
cutContract =
L.docGroup (SomeDocItem . MyGroup "b") $
L.doc (DDescription "a")
in L.renderLorentzDoc (L.cutLorentzNonDoc contract)
@?=
L.renderLorentzDoc cutContract
]
test_fakeCoerce :: [TestTree]
test_fakeCoerce =
[ testCase "Does not truncate the following documentation" $
let contract = L.doc (DDescription "a") :: '[] L.:-> '[]
in L.renderLorentzDoc (L.fakeCoerce # contract)
@?=
L.renderLorentzDoc contract
]