aboutsummaryrefslogtreecommitdiffstats
path: root/test/Test/Common.hs
blob: ffc3264bd6480b244300338d4041cfba7962c6ea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module Test.Common (W3CTestList (..), W3CTest (..), W3CTestOption (..), fetchTest, parseExpansionOptions) where

import Data.JLD.Prelude

import Test.Tasty
import Test.Tasty.ExpectedFailure (ignoreTestBecause)
import Test.Tasty.HUnit (assertFailure, testCase, (@?=))

import Data.Aeson (FromJSON (..), Value (..), (.:), (.:?))
import Data.Aeson.Types (prependFailure, typeMismatch)
import Data.JLD (DocumentLoader (..), JLDExpansionParams (..), JLDVersion (..), mimeType, toJldErrorCode)
import Data.JLD.Model.URI (parseUri)
import Data.Maybe (fromJust)
import Network.HTTP.Req (GET (..), NoReqBody (..), defaultHttpConfig, header, jsonResponse, req, responseBody, runReq, useHttpsURI, useURI)
import Text.URI (URI, mkURI, relativeTo)

data W3CTestOption = W3CTestOption
    { w3cTestOptionSpecVersion :: Maybe Text
    , w3cTestOptionProcessingMode :: Maybe Text
    , w3cTestOptionBase :: Maybe Text
    , w3cTestOptionExpandContext :: Maybe Text
    }
    deriving (Show)

instance FromJSON W3CTestOption where
    parseJSON (Object v) =
        W3CTestOption
            <$> (v .:? "specVersion")
            <*> (v .:? "processingMode")
            <*> (v .:? "base")
            <*> (v .:? "expandContext")
    parseJSON invalid = prependFailure "parsing W3CTestOption failed, " (typeMismatch "Object" invalid)

data W3CTest = W3CTest
    { w3cTestName :: Text
    , w3cTestInput :: Text
    , w3cTestExpect :: Maybe Text
    , w3cTestExpectErrorCode :: Maybe Text
    , w3cTestOption :: Maybe W3CTestOption
    }
    deriving (Show)

instance FromJSON W3CTest where
    parseJSON (Object v) =
        W3CTest
            <$> (v .: "name")
            <*> (v .: "input")
            <*> (v .:? "expect")
            <*> (v .:? "expectErrorCode")
            <*> (v .:? "option")
    parseJSON invalid = prependFailure "parsing W3CTest failed, " (typeMismatch "Object" invalid)

newtype W3CTestList = W3CTestList
    { w3cSequence :: [W3CTest]
    }
    deriving (Show)

instance FromJSON W3CTestList where
    parseJSON (Object v) = W3CTestList <$> (v .: "sequence")
    parseJSON invalid = prependFailure "parsing W3CTestList failed, " (typeMismatch "Object" invalid)

documentLoader :: MonadIO m => DocumentLoader Text m
documentLoader = DocumentLoader \uri ->
    runReq defaultHttpConfig <| case useURI uri of
        Just (Left (httpUri, options)) -> Right <. responseBody <$> req GET httpUri NoReqBody jsonResponse (options <> header "Accept" mimeType)
        Just (Right (httpsUri, options)) -> Right <. responseBody <$> req GET httpsUri NoReqBody jsonResponse (options <> header "Accept" mimeType)
        Nothing -> pure <| Left "Invalid URI"

fetchTest :: URI -> IO Value
fetchTest url = do
    let (reqUrl, reqOptions) = fromJust <| useHttpsURI url
    runReq defaultHttpConfig do
        res <- req GET reqUrl NoReqBody jsonResponse (reqOptions <> header "Accept" mimeType)
        pure <| responseBody res

parseExpansionOptions :: URI -> URI -> Maybe W3CTestOption -> IO (URI, JLDExpansionParams () IO -> JLDExpansionParams Text IO)
parseExpansionOptions baseUrl inputUrl maybeOptions = do
    expandContext <- case maybeOptions >>= w3cTestOptionExpandContext of
        Just rawUrl -> do
            url <- fromJust <. (`relativeTo` baseUrl) <$> mkURI rawUrl
            Just <$> fetchTest url
        Nothing -> pure Nothing

    let params p =
            p
                { jldExpansionParamsDocumentLoader = documentLoader
                , jldExpansionParamsProcessingMode = case maybeOptions >>= w3cTestOptionProcessingMode of
                    Just "json-ld-1.0" -> JLD1_0
                    Just "json-ld-1.1" -> JLD1_1
                    _ -> jldExpansionParamsProcessingMode p
                , jldExpansionParamsExpandContext = expandContext <|> jldExpansionParamsExpandContext p
                }

    pure (expandBaseUrl, params)
  where
    expandBaseUrl = fromMaybe inputUrl (parseUri =<< w3cTestOptionBase =<< maybeOptions)