aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolpeon <github@volpeon.ink>2023-05-28 08:13:08 +0200
committerVolpeon <github@volpeon.ink>2023-05-28 08:13:08 +0200
commit8c49a30faa431b8b56a4b4926e7dae56b1311fea (patch)
tree6a103b49cdfe6df38fadad1f9d59521dd92ebf74
parentAdded Node Map Merging algorithm (diff)
downloadhs-jsonld-8c49a30faa431b8b56a4b4926e7dae56b1311fea.tar.gz
hs-jsonld-8c49a30faa431b8b56a4b4926e7dae56b1311fea.tar.bz2
hs-jsonld-8c49a30faa431b8b56a4b4926e7dae56b1311fea.zip
Completed untested Flattening implementation
-rw-r--r--jsonld.cabal4
-rw-r--r--src/Data/JLD.hs9
-rw-r--r--src/Data/JLD/Flattening.hs44
-rw-r--r--src/Data/JLD/Flattening/Global.hs7
-rw-r--r--src/Data/JLD/Flattening/NodeMap.hs18
-rw-r--r--src/Data/JLD/Model/NodeMap.hs16
-rw-r--r--test/Spec.hs23
-rw-r--r--test/Test/Common.hs96
-rw-r--r--test/Test/Expansion.hs117
-rw-r--r--test/Test/Flattening.hs51
10 files changed, 268 insertions, 117 deletions
diff --git a/jsonld.cabal b/jsonld.cabal
index 9c9650c..0efa3b2 100644
--- a/jsonld.cabal
+++ b/jsonld.cabal
@@ -29,6 +29,8 @@ library
29 Data.JLD.Expansion 29 Data.JLD.Expansion
30 Data.JLD.Expansion.Context 30 Data.JLD.Expansion.Context
31 Data.JLD.Expansion.Global 31 Data.JLD.Expansion.Global
32 Data.JLD.Flattening
33 Data.JLD.Flattening.Global
32 Data.JLD.Flattening.NodeMap 34 Data.JLD.Flattening.NodeMap
33 Data.JLD.Mime 35 Data.JLD.Mime
34 Data.JLD.Model.ActiveContext 36 Data.JLD.Model.ActiveContext
@@ -89,7 +91,9 @@ test-suite jsonld-test
89 type: exitcode-stdio-1.0 91 type: exitcode-stdio-1.0
90 main-is: Spec.hs 92 main-is: Spec.hs
91 other-modules: 93 other-modules:
94 Test.Common
92 Test.Expansion 95 Test.Expansion
96 Test.Flattening
93 Paths_jsonld 97 Paths_jsonld
94 hs-source-dirs: 98 hs-source-dirs:
95 test 99 test
diff --git a/src/Data/JLD.hs b/src/Data/JLD.hs
index c5c28eb..d7688d0 100644
--- a/src/Data/JLD.hs
+++ b/src/Data/JLD.hs
@@ -5,6 +5,7 @@ module Data.JLD (
5 JLDExpansionParams (..), 5 JLDExpansionParams (..),
6 JLDExpansionState (..), 6 JLDExpansionState (..),
7 expand, 7 expand,
8 flatten,
8) where 9) where
9 10
10import Data.JLD.Prelude 11import Data.JLD.Prelude
@@ -15,6 +16,7 @@ import Data.JLD.Expansion (JLDEParams (..))
15import Data.JLD.Expansion qualified as E (expand) 16import Data.JLD.Expansion qualified as E (expand)
16import Data.JLD.Expansion.Context (buildActiveContext) 17import Data.JLD.Expansion.Context (buildActiveContext)
17import Data.JLD.Expansion.Global (JLDExpansionEnv (..), JLDExpansionState (..)) 18import Data.JLD.Expansion.Global (JLDExpansionEnv (..), JLDExpansionState (..))
19import Data.JLD.Flattening qualified as F (flatten)
18import Data.JLD.Mime 20import Data.JLD.Mime
19import Data.JLD.Model.ActiveContext (ActiveContext (..), newActiveContext) 21import Data.JLD.Model.ActiveContext (ActiveContext (..), newActiveContext)
20import Data.JLD.Model.Keyword (Keyword (..)) 22import Data.JLD.Model.Keyword (Keyword (..))
@@ -97,3 +99,10 @@ expand document baseUrl paramsFn = do
97 Left err -> Left err 99 Left err -> Left err
98 100
99 pure (result', state') 101 pure (result', state')
102
103flatten :: Monad m => Value -> URI -> (JLDExpansionParams () m -> JLDExpansionParams e m) -> m (Either (JLDError e) Value, JLDExpansionState)
104flatten document baseUrl paramsFn = do
105 (result, state') <- expand document baseUrl paramsFn
106 case result of
107 Left err -> pure (Left err, state')
108 Right expanded -> fmap (,state') <. runExceptT <| F.flatten expanded
diff --git a/src/Data/JLD/Flattening.hs b/src/Data/JLD/Flattening.hs
new file mode 100644
index 0000000..2bfd8dd
--- /dev/null
+++ b/src/Data/JLD/Flattening.hs
@@ -0,0 +1,44 @@
1module Data.JLD.Flattening (flatten) where
2
3import Data.JLD.Prelude
4
5import Data.JLD.Flattening.NodeMap (buildNodeMap)
6
7import Data.Aeson (Array, Value (..))
8import Data.Foldable.WithIndex (FoldableWithIndex (..))
9import Data.JLD.Flattening.Global (JLDFlatteningT)
10import Data.JLD.Model.Keyword (Keyword (..))
11import Data.JLD.Model.NodeMap (PropertyMap, SubjectMap, propsToKeyMap)
12import Data.Map qualified as M (insert, lookup, member, singleton, size)
13import Data.Vector qualified as V
14
15collectGraphsStep :: Text -> SubjectMap -> SubjectMap -> SubjectMap
16collectGraphsStep graphName dg graph
17 | graphName == show KeywordDefault = dg
18 | otherwise = M.insert (Just graphName) entry' dg
19 where
20 -- 4.1. 4.2.
21 entry = case M.lookup (Just graphName) dg of
22 Just e -> e
23 Nothing -> M.singleton (Just <| show KeywordId) (String graphName)
24
25 graphArray = Array <| foldl' collectNodesStep mempty graph
26
27 entry' = M.insert (Just <| show KeywordGraph) graphArray entry
28
29collectNodesStep :: Array -> PropertyMap -> Array
30collectNodesStep ar node
31 | M.size node == 1 && M.member (Just <| show KeywordId) node = ar
32 | otherwise = V.snoc ar (Object <| propsToKeyMap node)
33
34flatten :: Monad m => Value -> JLDFlatteningT e m Value
35flatten element = do
36 -- 1. 2.
37 nodeMap <- fst <$> buildNodeMap element id
38
39 -- 3. 4.
40 let defaultGraph = fromMaybe mempty <| M.lookup (show KeywordDefault) nodeMap
41 defaultGraph' = ifoldl' collectGraphsStep defaultGraph nodeMap
42
43 -- 5. 6. 7.
44 pure <. Array <| foldl' collectNodesStep mempty defaultGraph'
diff --git a/src/Data/JLD/Flattening/Global.hs b/src/Data/JLD/Flattening/Global.hs
new file mode 100644
index 0000000..591d3ad
--- /dev/null
+++ b/src/Data/JLD/Flattening/Global.hs
@@ -0,0 +1,7 @@
1module Data.JLD.Flattening.Global (JLDFlatteningT) where
2
3import Data.JLD.Prelude
4
5import Data.JLD.Error (JLDError)
6
7type JLDFlatteningT e m = ExceptT (JLDError e) m
diff --git a/src/Data/JLD/Flattening/NodeMap.hs b/src/Data/JLD/Flattening/NodeMap.hs
index 919aec7..65db9ab 100644
--- a/src/Data/JLD/Flattening/NodeMap.hs
+++ b/src/Data/JLD/Flattening/NodeMap.hs
@@ -2,8 +2,9 @@ module Data.JLD.Flattening.NodeMap (NodeMap, BNMParams (..), buildNodeMap, merge
2 2
3import Data.JLD.Prelude 3import Data.JLD.Prelude
4 4
5import Data.JLD.Control.Monad.RES (REST, execREST, withErrorRES') 5import Data.JLD.Control.Monad.RES (REST, runREST, withErrorRES')
6import Data.JLD.Error (JLDError (..)) 6import Data.JLD.Error (JLDError (..))
7import Data.JLD.Flattening.Global (JLDFlatteningT)
7import Data.JLD.Model.IRI (isBlankIri) 8import Data.JLD.Model.IRI (isBlankIri)
8import Data.JLD.Model.Keyword (Keyword (..), isKeywordLike, isNotKeyword) 9import Data.JLD.Model.Keyword (Keyword (..), isKeywordLike, isNotKeyword)
9import Data.JLD.Model.NodeMap (NodeMap, PropertyMap) 10import Data.JLD.Model.NodeMap (NodeMap, PropertyMap)
@@ -12,7 +13,7 @@ import Data.JLD.Model.NodeObject (isNodeObject)
12import Data.JLD.Util (valueIsScalar, valueToArray, valueToNonNullArray) 13import Data.JLD.Util (valueIsScalar, valueToArray, valueToNonNullArray)
13 14
14import Control.Monad.Except (MonadError (..)) 15import Control.Monad.Except (MonadError (..))
15import Data.Aeson (Array, Key, Object, Value (..)) 16import Data.Aeson (Array, Object, Value (..))
16import Data.Aeson.Key qualified as K (toText) 17import Data.Aeson.Key qualified as K (toText)
17import Data.Aeson.KeyMap qualified as KM (filterWithKey, insert, lookup, member, singleton) 18import Data.Aeson.KeyMap qualified as KM (filterWithKey, insert, lookup, member, singleton)
18import Data.Foldable.WithIndex (FoldableWithIndex (..), iforM_) 19import Data.Foldable.WithIndex (FoldableWithIndex (..), iforM_)
@@ -85,7 +86,10 @@ bnmBuildNodeMap value paramsFn = do
85 , bnmParamsActiveSubject = bnmEnvActiveSubject 86 , bnmParamsActiveSubject = bnmEnvActiveSubject
86 , bnmParamsActiveProperty = bnmEnvActiveProperty 87 , bnmParamsActiveProperty = bnmEnvActiveProperty
87 } 88 }
88 (nodeMap', list) <- buildNodeMap value params 89 (nodeMap', list) <-
90 buildNodeMap value params |> runExceptT >=> \case
91 Left err -> throwError <| Left err
92 Right a -> pure a
89 bnmModifyNodeMap <| const nodeMap' 93 bnmModifyNodeMap <| const nodeMap'
90 pure list 94 pure list
91 95
@@ -269,10 +273,12 @@ buildNodeMap' element = case element of
269 -- 273 --
270 _ -> pure () 274 _ -> pure ()
271 275
272buildNodeMap :: Monad m => Value -> (BNMParams -> BNMParams) -> m (NodeMap, Maybe Array) 276buildNodeMap :: Monad m => Value -> (BNMParams -> BNMParams) -> JLDFlatteningT e m (NodeMap, Maybe Array)
273buildNodeMap document paramsFn = do 277buildNodeMap document paramsFn = do
274 BNMState{..} <- buildNodeMap' document |> execREST env st 278 (result, BNMState{..}) <- buildNodeMap' document |> runREST env st
275 pure (bnmStateNodeMap, bnmStateList) 279 case result of
280 Left (Left err) -> throwError err
281 _ -> pure (bnmStateNodeMap, bnmStateList)
276 where 282 where
277 BNMParams{..} = 283 BNMParams{..} =
278 paramsFn 284 paramsFn
diff --git a/src/Data/JLD/Model/NodeMap.hs b/src/Data/JLD/Model/NodeMap.hs
index d0fb2f9..f76c662 100644
--- a/src/Data/JLD/Model/NodeMap.hs
+++ b/src/Data/JLD/Model/NodeMap.hs
@@ -10,13 +10,18 @@ module Data.JLD.Model.NodeMap (
10 hasKey2, 10 hasKey2,
11 hasKey3, 11 hasKey3,
12 memberArray, 12 memberArray,
13 propsToKeyMap,
13) where 14) where
14 15
15import Data.JLD.Prelude hiding (modify) 16import Data.JLD.Prelude hiding (modify)
16 17
17import Data.Aeson (Array, Value (..)) 18import Data.Aeson (Array, Value (..))
19import Data.Aeson.Key qualified as K
20import Data.Aeson.KeyMap (KeyMap)
21import Data.Aeson.KeyMap qualified as KM
22import Data.Foldable.WithIndex (FoldableWithIndex (..))
18import Data.JLD.Util (valueToArray) 23import Data.JLD.Util (valueToArray)
19import Data.Map.Strict qualified as M (alter, insert, lookup, member) 24import Data.Map.Strict qualified as M (alter, insert, lookup, member, toList)
20 25
21type PropertyKey = Maybe Text 26type PropertyKey = Maybe Text
22type PropertyMap = Map PropertyKey Value 27type PropertyMap = Map PropertyKey Value
@@ -55,3 +60,12 @@ memberArray :: GraphKey -> SubjectKey -> PropertyKey -> Value -> NodeMap -> Bool
55memberArray graphName subject property value nodeMap = case lookup3 graphName subject property nodeMap of 60memberArray graphName subject property value nodeMap = case lookup3 graphName subject property nodeMap of
56 Just (Array a) -> value `elem` a 61 Just (Array a) -> value `elem` a
57 _ -> False 62 _ -> False
63
64propsToKeyMap :: PropertyMap -> KeyMap Value
65propsToKeyMap =
66 ifoldl'
67 ( \maybeKey km value -> case maybeKey of
68 Just key -> KM.insert (K.fromText key) value km
69 Nothing -> km
70 )
71 mempty
diff --git a/test/Spec.hs b/test/Spec.hs
index c58bbfa..c85ac53 100644
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,24 +1,31 @@
1import Data.JLD.Prelude 1import Data.JLD.Prelude
2 2
3import Data.JLD.Mime (mimeType)
4import Test.Expansion (W3CExpansionTestList, expansionTests)
5
6import Test.Tasty 3import Test.Tasty
7 4
5import Data.JLD.Mime (mimeType)
6import Test.Common (W3CTestList)
7import Test.Expansion (expansionTests)
8import Test.Flattening (flatteningTests)
9
8import Network.HTTP.Req (GET (..), NoReqBody (..), defaultHttpConfig, header, https, jsonResponse, req, responseBody, runReq, (/:)) 10import Network.HTTP.Req (GET (..), NoReqBody (..), defaultHttpConfig, header, https, jsonResponse, req, responseBody, runReq, (/:))
9 11
10tests :: W3CExpansionTestList -> TestTree 12tests :: W3CTestList -> W3CTestList -> TestTree
11tests jldExpansionTestList = 13tests expansionTestList flatteningTestList =
12 testGroup 14 testGroup
13 "Tests" 15 "Tests"
14 [ expansionTests jldExpansionTestList 16 [ expansionTests expansionTestList
17 , flatteningTests flatteningTestList
15 ] 18 ]
16 19
17main :: IO () 20main :: IO ()
18main = do 21main = do
19 jldExpansionTestList <- runReq defaultHttpConfig do 22 expansionTestList <- runReq defaultHttpConfig do
20 responseBody <$> req GET w3cExpansionTestListUrl NoReqBody jsonResponse (header "Accept" mimeType) 23 responseBody <$> req GET w3cExpansionTestListUrl NoReqBody jsonResponse (header "Accept" mimeType)
21 24
22 defaultMain <| tests jldExpansionTestList 25 flatteningTestList <- runReq defaultHttpConfig do
26 responseBody <$> req GET w3cFlatteningTestListUrl NoReqBody jsonResponse (header "Accept" mimeType)
27
28 defaultMain <| tests expansionTestList flatteningTestList
23 where 29 where
24 w3cExpansionTestListUrl = https "w3c.github.io" /: "json-ld-api" /: "tests" /: "expand-manifest.jsonld" 30 w3cExpansionTestListUrl = https "w3c.github.io" /: "json-ld-api" /: "tests" /: "expand-manifest.jsonld"
31 w3cFlatteningTestListUrl = https "w3c.github.io" /: "json-ld-api" /: "tests" /: "flatten-manifest.jsonld"
diff --git a/test/Test/Common.hs b/test/Test/Common.hs
new file mode 100644
index 0000000..ffc3264
--- /dev/null
+++ b/test/Test/Common.hs
@@ -0,0 +1,96 @@
1module Test.Common (W3CTestList (..), W3CTest (..), W3CTestOption (..), fetchTest, parseExpansionOptions) where
2
3import Data.JLD.Prelude
4
5import Test.Tasty
6import Test.Tasty.ExpectedFailure (ignoreTestBecause)
7import Test.Tasty.HUnit (assertFailure, testCase, (@?=))
8
9import Data.Aeson (FromJSON (..), Value (..), (.:), (.:?))
10import Data.Aeson.Types (prependFailure, typeMismatch)
11import Data.JLD (DocumentLoader (..), JLDExpansionParams (..), JLDVersion (..), mimeType, toJldErrorCode)
12import Data.JLD.Model.URI (parseUri)
13import Data.Maybe (fromJust)
14import Network.HTTP.Req (GET (..), NoReqBody (..), defaultHttpConfig, header, jsonResponse, req, responseBody, runReq, useHttpsURI, useURI)
15import Text.URI (URI, mkURI, relativeTo)
16
17data W3CTestOption = W3CTestOption
18 { w3cTestOptionSpecVersion :: Maybe Text
19 , w3cTestOptionProcessingMode :: Maybe Text
20 , w3cTestOptionBase :: Maybe Text
21 , w3cTestOptionExpandContext :: Maybe Text
22 }
23 deriving (Show)
24
25instance FromJSON W3CTestOption where
26 parseJSON (Object v) =
27 W3CTestOption
28 <$> (v .:? "specVersion")
29 <*> (v .:? "processingMode")
30 <*> (v .:? "base")
31 <*> (v .:? "expandContext")
32 parseJSON invalid = prependFailure "parsing W3CTestOption failed, " (typeMismatch "Object" invalid)
33
34data W3CTest = W3CTest
35 { w3cTestName :: Text
36 , w3cTestInput :: Text
37 , w3cTestExpect :: Maybe Text
38 , w3cTestExpectErrorCode :: Maybe Text
39 , w3cTestOption :: Maybe W3CTestOption
40 }
41 deriving (Show)
42
43instance FromJSON W3CTest where
44 parseJSON (Object v) =
45 W3CTest
46 <$> (v .: "name")
47 <*> (v .: "input")
48 <*> (v .:? "expect")
49 <*> (v .:? "expectErrorCode")
50 <*> (v .:? "option")
51 parseJSON invalid = prependFailure "parsing W3CTest failed, " (typeMismatch "Object" invalid)
52
53newtype W3CTestList = W3CTestList
54 { w3cSequence :: [W3CTest]
55 }
56 deriving (Show)
57
58instance FromJSON W3CTestList where
59 parseJSON (Object v) = W3CTestList <$> (v .: "sequence")
60 parseJSON invalid = prependFailure "parsing W3CTestList failed, " (typeMismatch "Object" invalid)
61
62documentLoader :: MonadIO m => DocumentLoader Text m
63documentLoader = DocumentLoader \uri ->
64 runReq defaultHttpConfig <| case useURI uri of
65 Just (Left (httpUri, options)) -> Right <. responseBody <$> req GET httpUri NoReqBody jsonResponse (options <> header "Accept" mimeType)
66 Just (Right (httpsUri, options)) -> Right <. responseBody <$> req GET httpsUri NoReqBody jsonResponse (options <> header "Accept" mimeType)
67 Nothing -> pure <| Left "Invalid URI"
68
69fetchTest :: URI -> IO Value
70fetchTest url = do
71 let (reqUrl, reqOptions) = fromJust <| useHttpsURI url
72 runReq defaultHttpConfig do
73 res <- req GET reqUrl NoReqBody jsonResponse (reqOptions <> header "Accept" mimeType)
74 pure <| responseBody res
75
76parseExpansionOptions :: URI -> URI -> Maybe W3CTestOption -> IO (URI, JLDExpansionParams () IO -> JLDExpansionParams Text IO)
77parseExpansionOptions baseUrl inputUrl maybeOptions = do
78 expandContext <- case maybeOptions >>= w3cTestOptionExpandContext of
79 Just rawUrl -> do
80 url <- fromJust <. (`relativeTo` baseUrl) <$> mkURI rawUrl
81 Just <$> fetchTest url
82 Nothing -> pure Nothing
83
84 let params p =
85 p
86 { jldExpansionParamsDocumentLoader = documentLoader
87 , jldExpansionParamsProcessingMode = case maybeOptions >>= w3cTestOptionProcessingMode of
88 Just "json-ld-1.0" -> JLD1_0
89 Just "json-ld-1.1" -> JLD1_1
90 _ -> jldExpansionParamsProcessingMode p
91 , jldExpansionParamsExpandContext = expandContext <|> jldExpansionParamsExpandContext p
92 }
93
94 pure (expandBaseUrl, params)
95 where
96 expandBaseUrl = fromMaybe inputUrl (parseUri =<< w3cTestOptionBase =<< maybeOptions)
diff --git a/test/Test/Expansion.hs b/test/Test/Expansion.hs
index 89024c6..b5b1e07 100644
--- a/test/Test/Expansion.hs
+++ b/test/Test/Expansion.hs
@@ -1,134 +1,47 @@
1module Test.Expansion (W3CExpansionTestList, expansionTests) where 1module Test.Expansion (expansionTests) where
2 2
3import Data.JLD.Prelude 3import Data.JLD.Prelude
4 4
5import Data.JLD (DocumentLoader (..), JLDExpansionParams (..), JLDVersion (..), expand, mimeType, toJldErrorCode)
6import Data.JLD.Model.URI (parseUri)
7
8import Test.Tasty 5import Test.Tasty
9import Test.Tasty.ExpectedFailure (ignoreTestBecause) 6import Test.Tasty.ExpectedFailure (ignoreTestBecause)
10import Test.Tasty.HUnit 7import Test.Tasty.HUnit
11 8
12import Data.Aeson (FromJSON, Value (..), (.:), (.:?)) 9import Data.JLD (expand, toJldErrorCode)
13import Data.Aeson.Types (FromJSON (..), prependFailure, typeMismatch)
14import Data.Maybe (fromJust) 10import Data.Maybe (fromJust)
15import Network.HTTP.Req (GET (..), NoReqBody (..), defaultHttpConfig, header, jsonResponse, req, responseBody, runReq, useHttpsURI, useURI) 11import Test.Common (W3CTest (..), W3CTestList (..), W3CTestOption (..), fetchTest, parseExpansionOptions)
16import Text.URI (URI, mkURI, relativeTo) 12import Text.URI (mkURI, relativeTo)
17
18data W3CExpansionTestOption = W3CExpansionTestOption
19 { w3cExpansionTestOptionSpecVersion :: Maybe Text
20 , w3cExpansionTestOptionProcessingMode :: Maybe Text
21 , w3cExpansionTestOptionBase :: Maybe Text
22 , w3cExpansionTestOptionExpandContext :: Maybe Text
23 }
24 deriving (Show)
25
26instance FromJSON W3CExpansionTestOption where
27 parseJSON (Object v) =
28 W3CExpansionTestOption
29 <$> (v .:? "specVersion")
30 <*> (v .:? "processingMode")
31 <*> (v .:? "base")
32 <*> (v .:? "expandContext")
33 parseJSON invalid = prependFailure "parsing W3CExpansionTestOption failed, " (typeMismatch "Object" invalid)
34
35data W3CExpansionTest = W3CExpansionTest
36 { w3cExpansionTestName :: Text
37 , w3cExpansionTestInput :: Text
38 , w3cExpansionTestExpect :: Maybe Text
39 , w3cExpansionTestExpectErrorCode :: Maybe Text
40 , w3cExpansionTestOption :: Maybe W3CExpansionTestOption
41 }
42 deriving (Show)
43
44instance FromJSON W3CExpansionTest where
45 parseJSON (Object v) =
46 W3CExpansionTest
47 <$> (v .: "name")
48 <*> (v .: "input")
49 <*> (v .:? "expect")
50 <*> (v .:? "expectErrorCode")
51 <*> (v .:? "option")
52 parseJSON invalid = prependFailure "parsing W3CExpansionTest failed, " (typeMismatch "Object" invalid)
53
54newtype W3CExpansionTestList = W3CExpansionTestList
55 { w3cExpansionSequence :: [W3CExpansionTest]
56 }
57 deriving (Show)
58
59instance FromJSON W3CExpansionTestList where
60 parseJSON (Object v) = W3CExpansionTestList <$> (v .: "sequence")
61 parseJSON invalid = prependFailure "parsing W3CExpansionTestList failed, " (typeMismatch "Object" invalid)
62 13
63documentLoader :: MonadIO m => DocumentLoader Text m 14expansionTests :: W3CTestList -> TestTree
64documentLoader = DocumentLoader \uri -> 15expansionTests testList = testGroup "Expansion" <| uncurry expansionTest <$> zip (w3cSequence testList) [1 ..]
65 runReq defaultHttpConfig <| case useURI uri of
66 Just (Left (httpUri, options)) -> Right <. responseBody <$> req GET httpUri NoReqBody jsonResponse (options <> header "Accept" mimeType)
67 Just (Right (httpsUri, options)) -> Right <. responseBody <$> req GET httpsUri NoReqBody jsonResponse (options <> header "Accept" mimeType)
68 Nothing -> pure <| Left "Invalid URI"
69 16
70fetchTest :: URI -> IO Value 17expansionTest :: W3CTest -> Int -> TestTree
71fetchTest url = do 18expansionTest W3CTest{..} (show .> (<> ". " <> toString w3cTestName) -> testName)
72 let (reqUrl, reqOptions) = fromJust <| useHttpsURI url 19 | Just "json-ld-1.0" <- w3cTestOptionSpecVersion =<< w3cTestOption =
73 runReq defaultHttpConfig do
74 res <- req GET reqUrl NoReqBody jsonResponse (reqOptions <> header "Accept" mimeType)
75 pure <| responseBody res
76
77parseOptions :: URI -> URI -> Maybe W3CExpansionTestOption -> IO (URI, JLDExpansionParams () IO -> JLDExpansionParams Text IO)
78parseOptions baseUrl inputUrl maybeOptions = do
79 expandContext <- case maybeOptions >>= w3cExpansionTestOptionExpandContext of
80 Just rawUrl -> do
81 url <- fromJust <. (`relativeTo` baseUrl) <$> mkURI rawUrl
82 Just <$> fetchTest url
83 Nothing -> pure Nothing
84
85 let params p =
86 p
87 { jldExpansionParamsDocumentLoader = documentLoader
88 , jldExpansionParamsProcessingMode = case maybeOptions >>= w3cExpansionTestOptionProcessingMode of
89 Just "json-ld-1.0" -> JLD1_0
90 Just "json-ld-1.1" -> JLD1_1
91 _ -> jldExpansionParamsProcessingMode p
92 , jldExpansionParamsExpandContext = expandContext <|> jldExpansionParamsExpandContext p
93 }
94
95 pure (expandBaseUrl, params)
96 where
97 expandBaseUrl = fromMaybe inputUrl (parseUri =<< w3cExpansionTestOptionBase =<< maybeOptions)
98
99expansionTests :: W3CExpansionTestList -> TestTree
100expansionTests testList = testGroup "Expansion" <| uncurry expansionTest <$> (take 999 <. drop 0 <| zip (w3cExpansionSequence testList) [1 ..])
101
102expansionTest :: W3CExpansionTest -> Int -> TestTree
103expansionTest W3CExpansionTest{..} (show .> (<> ". " <> toString w3cExpansionTestName) -> testName)
104 | Just "json-ld-1.0" <- w3cExpansionTestOptionSpecVersion =<< w3cExpansionTestOption =
105 ignoreTestBecause "specVersion json-ld-1.0 is not supported" 20 ignoreTestBecause "specVersion json-ld-1.0 is not supported"
106 <| testCase testName do pure () 21 <| testCase testName do pure ()
107 -- 22 --
108 | Just expectUrlRaw <- w3cExpansionTestExpect = 23 | Just expectUrlRaw <- w3cTestExpect =
109 testCase testName do 24 testCase testName do
110 baseUrl <- mkURI "https://w3c.github.io/json-ld-api/tests/" 25 baseUrl <- mkURI "https://w3c.github.io/json-ld-api/tests/"
111 inputUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI w3cExpansionTestInput 26 inputUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI w3cTestInput
112 expectUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI expectUrlRaw 27 expectUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI expectUrlRaw
113 28
114 inputJld <- fetchTest inputUrl 29 inputJld <- fetchTest inputUrl
115 expectJld <- fetchTest expectUrl 30 expectJld <- fetchTest expectUrl
116 31
117 (expandBaseUrl, params) <- parseOptions baseUrl inputUrl w3cExpansionTestOption 32 (expandBaseUrl, params) <- parseExpansionOptions baseUrl inputUrl w3cTestOption
118 (result, _) <- expand inputJld expandBaseUrl params 33 (result, _) <- expand inputJld expandBaseUrl params
119 34
120 -- pTraceShowM (expectJLD, result)
121
122 result @?= Right expectJld 35 result @?= Right expectJld
123 -- 36 --
124 | Just expectErrorRaw <- w3cExpansionTestExpectErrorCode = 37 | Just expectErrorRaw <- w3cTestExpectErrorCode =
125 testCase testName do 38 testCase testName do
126 baseUrl <- mkURI "https://w3c.github.io/json-ld-api/tests/" 39 baseUrl <- mkURI "https://w3c.github.io/json-ld-api/tests/"
127 inputUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI w3cExpansionTestInput 40 inputUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI w3cTestInput
128 41
129 inputJld <- fetchTest inputUrl 42 inputJld <- fetchTest inputUrl
130 43
131 (expandBaseUrl, params) <- parseOptions baseUrl inputUrl w3cExpansionTestOption 44 (expandBaseUrl, params) <- parseExpansionOptions baseUrl inputUrl w3cTestOption
132 (result, _) <- expand inputJld expandBaseUrl params 45 (result, _) <- expand inputJld expandBaseUrl params
133 46
134 (result |> first toJldErrorCode) @?= Left expectErrorRaw 47 (result |> first toJldErrorCode) @?= Left expectErrorRaw
diff --git a/test/Test/Flattening.hs b/test/Test/Flattening.hs
new file mode 100644
index 0000000..bc64b88
--- /dev/null
+++ b/test/Test/Flattening.hs
@@ -0,0 +1,51 @@
1module Test.Flattening (flatteningTests) where
2
3import Data.JLD.Prelude
4
5import Test.Tasty
6import Test.Tasty.ExpectedFailure (ignoreTestBecause)
7import Test.Tasty.HUnit
8
9import Data.JLD (expand, flatten, toJldErrorCode)
10import Data.Maybe (fromJust)
11import Test.Common (W3CTest (..), W3CTestList (..), W3CTestOption (..), fetchTest, parseExpansionOptions)
12import Text.URI (mkURI, relativeTo)
13
14flatteningTests :: W3CTestList -> TestTree
15flatteningTests testList = testGroup "Flattening" <| uncurry flatteningTest <$> zip (w3cSequence testList) [1 ..]
16
17flatteningTest :: W3CTest -> Int -> TestTree
18flatteningTest W3CTest{..} (show .> (<> ". " <> toString w3cTestName) -> testName)
19 | Just "json-ld-1.0" <- w3cTestOptionSpecVersion =<< w3cTestOption =
20 ignoreTestBecause "specVersion json-ld-1.0 is not supported"
21 <| testCase testName do pure ()
22 --
23 | Just expectUrlRaw <- w3cTestExpect =
24 testCase testName do
25 baseUrl <- mkURI "https://w3c.github.io/json-ld-api/tests/"
26 inputUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI w3cTestInput
27 expectUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI expectUrlRaw
28
29 inputJld <- fetchTest inputUrl
30 expectJld <- fetchTest expectUrl
31
32 (expandBaseUrl, params) <- parseExpansionOptions baseUrl inputUrl w3cTestOption
33 (result, _) <- flatten inputJld expandBaseUrl params
34
35 result @?= Right expectJld
36 --
37 | Just expectErrorRaw <- w3cTestExpectErrorCode =
38 testCase testName do
39 baseUrl <- mkURI "https://w3c.github.io/json-ld-api/tests/"
40 inputUrl <- fromJust <. (`relativeTo` baseUrl) <$> mkURI w3cTestInput
41
42 inputJld <- fetchTest inputUrl
43
44 (expandBaseUrl, params) <- parseExpansionOptions baseUrl inputUrl w3cTestOption
45 (result, _) <- flatten inputJld expandBaseUrl params
46
47 (result |> first toJldErrorCode) @?= Left expectErrorRaw
48 --
49 | otherwise =
50 testCase testName do
51 assertFailure <| "Unhandled test type"