feat: add SchemaOrgRecipe types and FromJSON parsing
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
module Roux.SchemaOrgSpec (spec) where
|
||||
|
||||
import qualified Data.Aeson as A
|
||||
import Data.Maybe (fromJust, isJust)
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as TE
|
||||
import Test.Hspec (Spec, describe, expectationFailure, it, shouldBe, shouldSatisfy)
|
||||
|
||||
import Roux.SchemaOrg
|
||||
|
||||
-- | Extract the first schema.org Recipe JSON-LD from HTML.
|
||||
tryDecode :: Text -> Maybe A.Value
|
||||
tryDecode html =
|
||||
case T.splitOn "<script type=\"application/ld+json" html of
|
||||
(_before : rest : _) ->
|
||||
-- Skip past the closing > of the opening script tag, which may have extra attributes
|
||||
let afterOpenTag = T.drop 1 (T.dropWhile (/= '>') rest)
|
||||
in case T.splitOn "</script>" afterOpenTag of
|
||||
(jsonContent : _) -> A.decodeStrict (TE.encodeUtf8 (T.strip jsonContent))
|
||||
_ -> Nothing
|
||||
_ -> Nothing
|
||||
|
||||
spec :: Spec
|
||||
spec = describe "SchemaOrg" $ do
|
||||
describe "parseSchemaOrgRecipe" $ do
|
||||
it "parses fried-rice.html embedded JSON-LD" $ do
|
||||
html <- readFile "test-data/fried-rice.html"
|
||||
let decoded = tryDecode (T.pack html)
|
||||
decoded `shouldSatisfy` isJust
|
||||
let recipe = parseSchemaOrgRecipe (fromJust decoded)
|
||||
recipe `shouldSatisfy` isJust
|
||||
case recipe of
|
||||
Nothing -> expectationFailure "expected Just SchemaOrgRecipe, got Nothing"
|
||||
Just r -> do
|
||||
soName r `shouldBe` "Fried Rice"
|
||||
soRecipeYield r `shouldBe` Just "4 to 6 servings"
|
||||
soTotalTime r `shouldBe` Just "PT20M"
|
||||
soRecipeCuisine r `shouldBe` Just "asian"
|
||||
length (soRecipeIngredient r) `shouldBe` 14
|
||||
length (soRecipeInstructions r) `shouldBe` 4
|
||||
|
||||
it "parses carrot-risotto.html embedded JSON-LD" $ do
|
||||
html <- readFile "test-data/carrot-risotto.html"
|
||||
let decoded = tryDecode (T.pack html)
|
||||
decoded `shouldSatisfy` isJust
|
||||
let recipe = parseSchemaOrgRecipe (fromJust decoded)
|
||||
recipe `shouldSatisfy` isJust
|
||||
case recipe of
|
||||
Nothing -> expectationFailure "expected Just SchemaOrgRecipe, got Nothing"
|
||||
Just r -> soName r `shouldBe` "Carrot Risotto With Chile Crisp"
|
||||
@@ -5,14 +5,17 @@ import Test.Tasty.Hspec (testSpec)
|
||||
|
||||
import qualified Roux.NYTimesSpec
|
||||
import qualified Roux.ParserSpec
|
||||
import qualified Roux.SchemaOrgSpec
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
parserTests <- testSpec "Parser" Roux.ParserSpec.spec
|
||||
nytTests <- testSpec "NYTimes" Roux.NYTimesSpec.spec
|
||||
schemaOrgTests <- testSpec "SchemaOrg" Roux.SchemaOrgSpec.spec
|
||||
defaultMain $
|
||||
testGroup
|
||||
"roux-server"
|
||||
[ parserTests
|
||||
, nytTests
|
||||
, schemaOrgTests
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user