test: add step count preservation tests for SchemaOrg → Cooklang conversion
Build and Deploy / build-and-deploy (push) Successful in 1m14s
Build and Deploy / build-and-deploy (push) Successful in 1m14s
Adds checkStepCount helper that verifies the number of instructions in the parsed schema.org recipe matches the number of SecStep items in the Method section of the resulting Cooklang Recipe. Tests both fried-rice (4 steps) and carrot-risotto (7 steps).
This commit is contained in:
+65
-31
@@ -1,7 +1,7 @@
|
||||
module Roux.SchemaOrgSpec (spec) where
|
||||
|
||||
import Data.Aeson (Value, decodeStrict)
|
||||
import Data.CookLang (Duration (..), Metadata (..), Recipe (..))
|
||||
import Data.CookLang (Duration (..), Metadata (..), Recipe (..), Section (..), SectionBodyItem (..))
|
||||
import Data.List.NonEmpty (toList)
|
||||
import Data.Maybe (fromJust, isJust)
|
||||
import Data.Text (Text)
|
||||
@@ -66,34 +66,68 @@ spec = describe "SchemaOrg" $ do
|
||||
it "human-readable -> Nothing" $ chk "20 minutes" Nothing
|
||||
|
||||
describe "schemaOrgToCooklang" $ do
|
||||
it "converts fried-rice schema.org recipe to Cooklang" $ do
|
||||
html <- readFile "test-data/fried-rice.html"
|
||||
let decoded = tryDecode (T.pack html)
|
||||
recipe = parseSchemaOrgRecipe (fromJust decoded)
|
||||
case recipe of
|
||||
Just r -> case schemaOrgToCooklang r of
|
||||
Right cook -> do
|
||||
metaTitle (recipeMetadata cook) `shouldBe` Just "Fried Rice"
|
||||
metaSource (recipeMetadata cook) `shouldBe` Just "https://cooking.nytimes.com/recipes/12177-fried-rice"
|
||||
metaCourse (recipeMetadata cook) `shouldBe` Just "one pot, side dish"
|
||||
metaCuisine (recipeMetadata cook) `shouldBe` Just "asian"
|
||||
metaTotalTime (recipeMetadata cook) `shouldBe` Just (Duration 20 (Just "minutes"))
|
||||
metaTags (recipeMetadata cook) `shouldBe` ["egg", "rice", "vegetarian"]
|
||||
metaDescription (recipeMetadata cook) `shouldSatisfy` isJust
|
||||
let sections = toList (recipeSections cook)
|
||||
length sections `shouldBe` 2
|
||||
Left err -> fail err
|
||||
Nothing -> fail "Failed to parse schema.org recipe"
|
||||
let loadRecipeFile :: FilePath -> IO (Maybe SchemaOrgRecipe)
|
||||
loadRecipeFile path = do
|
||||
html <- readFile path
|
||||
let decoded = tryDecode (T.pack html)
|
||||
pure (parseSchemaOrgRecipe =<< decoded)
|
||||
|
||||
it "converts carrot-risotto schema.org recipe to Cooklang" $ do
|
||||
html <- readFile "test-data/carrot-risotto.html"
|
||||
let decoded = tryDecode (T.pack html)
|
||||
recipe = parseSchemaOrgRecipe (fromJust decoded)
|
||||
case recipe of
|
||||
Just r -> case schemaOrgToCooklang r of
|
||||
Right cook -> do
|
||||
metaTitle (recipeMetadata cook) `shouldBe` Just "Carrot Risotto With Chile Crisp"
|
||||
metaAuthor (recipeMetadata cook) `shouldBe` Just "Alexa Weibel"
|
||||
metaTags (recipeMetadata cook) `shouldSatisfy` (not . null)
|
||||
Left err -> fail err
|
||||
Nothing -> fail "Failed to parse schema.org recipe"
|
||||
let countMethodSteps :: Recipe -> Int
|
||||
countMethodSteps recipe =
|
||||
let sections = toList (recipeSections recipe)
|
||||
in case filter (\s -> sectionName s == Just "Method") sections of
|
||||
[s] ->
|
||||
let bodyItems = toList (sectionBody s)
|
||||
in length [() | SecStep _ <- bodyItems]
|
||||
_ -> 0
|
||||
|
||||
let checkStepCount :: FilePath -> String -> Int -> Spec
|
||||
checkStepCount path label expectedSteps = it ("preserves " <> label <> " step count in Cooklang conversion") $ do
|
||||
mRecipe <- loadRecipeFile path
|
||||
case mRecipe of
|
||||
Nothing -> fail "Failed to parse schema.org recipe"
|
||||
Just r -> do
|
||||
let rawInstructions = soRecipeInstructions r
|
||||
length rawInstructions `shouldBe` expectedSteps
|
||||
case schemaOrgToCooklang r of
|
||||
Left err -> fail err
|
||||
Right cook -> do
|
||||
let cookSteps = countMethodSteps cook
|
||||
cookSteps `shouldBe` expectedSteps
|
||||
|
||||
let checkMetadata :: FilePath -> String -> (SchemaOrgRecipe -> IO ()) -> Spec
|
||||
checkMetadata path label checks = it ("converts " <> label <> " schema.org recipe to Cooklang") $ do
|
||||
mRecipe <- loadRecipeFile path
|
||||
case mRecipe of
|
||||
Nothing -> fail "Failed to parse schema.org recipe"
|
||||
Just r -> do
|
||||
checks r
|
||||
case schemaOrgToCooklang r of
|
||||
Left err -> fail err
|
||||
Right _ -> pure ()
|
||||
|
||||
checkStepCount "test-data/fried-rice.html" "fried-rice" 4
|
||||
|
||||
checkStepCount "test-data/carrot-risotto.html" "carrot-risotto" 7
|
||||
|
||||
checkMetadata "test-data/fried-rice.html" "fried-rice" $ \r ->
|
||||
case schemaOrgToCooklang r of
|
||||
Left err -> fail err
|
||||
Right cook -> do
|
||||
metaTitle (recipeMetadata cook) `shouldBe` Just "Fried Rice"
|
||||
metaSource (recipeMetadata cook) `shouldBe` Just "https://cooking.nytimes.com/recipes/12177-fried-rice"
|
||||
metaCourse (recipeMetadata cook) `shouldBe` Just "one pot, side dish"
|
||||
metaCuisine (recipeMetadata cook) `shouldBe` Just "asian"
|
||||
metaTotalTime (recipeMetadata cook) `shouldBe` Just (Duration 20 (Just "minutes"))
|
||||
metaTags (recipeMetadata cook) `shouldBe` ["egg", "rice", "vegetarian"]
|
||||
metaDescription (recipeMetadata cook) `shouldSatisfy` isJust
|
||||
let sections = toList (recipeSections cook)
|
||||
length sections `shouldBe` 2
|
||||
|
||||
checkMetadata "test-data/carrot-risotto.html" "carrot-risotto" $ \r ->
|
||||
case schemaOrgToCooklang r of
|
||||
Left err -> fail err
|
||||
Right cook -> do
|
||||
metaTitle (recipeMetadata cook) `shouldBe` Just "Carrot Risotto With Chile Crisp"
|
||||
metaAuthor (recipeMetadata cook) `shouldBe` Just "Alexa Weibel"
|
||||
metaTags (recipeMetadata cook) `shouldSatisfy` (not . null)
|
||||
|
||||
Reference in New Issue
Block a user