module Roux.NYTimesSpec (spec) where import qualified Data.Text.IO as TIO import Test.Hspec (Spec, describe, it, shouldBe, shouldSatisfy) import Data.CookLang import Roux.NYTimes spec :: Spec spec = do describe "extractNextData" $ do it "extracts JSON from fried-rice.html" $ do html <- TIO.readFile "test-data/fried-rice.html" let result = extractNextData html result `shouldSatisfy` isJust it "extracts JSON from carrot-risotto.html" $ do html <- TIO.readFile "test-data/carrot-risotto.html" let result = extractNextData html result `shouldSatisfy` isJust describe "parseNYTRecipe" $ do it "parses fried-rice.html recipe correctly" $ do html <- TIO.readFile "test-data/fried-rice.html" let result = do val <- extractNextData html parseNYTRecipe val case result of Nothing -> error "failed to parse fried-rice recipe" Just recipe -> do nytTitle recipe `shouldBe` "Fried Rice" nytUrl recipe `shouldBe` Just "https://cooking.nytimes.com/recipes/12177-fried-rice" nytTotalTime recipe `shouldBe` Just "20 minutes" nytRecipeYield recipe `shouldBe` Just "4 to 6 servings" nytTopnote recipe `shouldSatisfy` isJust length (nytIngredientGroups recipe) `shouldBe` 1 case nytIngredientGroups recipe of [group] -> do length (nytIngredients group) `shouldBe` 14 case nytIngredients group of (firstIng : _) -> do nytIngredientText firstIng `shouldBe` "tablespoons neutral oil, like canola or grapeseed" nytIngredientQuantity firstIng `shouldBe` "3" [] -> error "empty ingredient group" _ -> error "expected 1 ingredient group" case nytStepGroups recipe of [stepGroup] -> do length (nytSteps stepGroup) `shouldBe` 4 case nytSteps stepGroup of (firstStep : _) -> nytStepNumber firstStep `shouldBe` 1 [] -> error "empty step group" _ -> error "expected 1 step group" it "parses carrot-risotto.html recipe correctly" $ do html <- TIO.readFile "test-data/carrot-risotto.html" let result = do val <- extractNextData html parseNYTRecipe val case result of Nothing -> error "failed to parse carrot-risotto recipe" Just recipe -> do nytTitle recipe `shouldBe` "Carrot Risotto With Chile Crisp" nytUrl recipe `shouldBe` Just "https://cooking.nytimes.com/recipes/1024086-carrot-risotto-with-chile-crisp" nytTotalTime recipe `shouldBe` Just "30 minutes" nytRecipeYield recipe `shouldBe` Just "4 servings" length (nytIngredientGroups recipe) `shouldBe` 1 case nytIngredientGroups recipe of [group] -> length (nytIngredients group) `shouldBe` 11 _ -> error "expected 1 ingredient group" case nytStepGroups recipe of [stepGroup] -> length (nytSteps stepGroup) `shouldBe` 7 _ -> error "expected 1 step group" describe "nytToCooklang" $ do it "converts fried-rice NYTRecipe to Cooklang Recipe" $ do html <- TIO.readFile "test-data/fried-rice.html" let result = do val <- extractNextData html nyt <- parseNYTRecipe val pure (nytToCooklang nyt) case result of Nothing -> error "failed to parse/convert fried-rice" Just recipe -> do metaTitle (recipeMetadata recipe) `shouldBe` Just "Fried Rice" metaSource (recipeMetadata recipe) `shouldBe` Just "https://cooking.nytimes.com/recipes/12177-fried-rice" metaTotalTime (recipeMetadata recipe) `shouldBe` Just (Duration 20 (Just "minutes")) length (recipeSections recipe) `shouldSatisfy` (> 0) it "converts carrot-risotto NYTRecipe to Cooklang Recipe" $ do html <- TIO.readFile "test-data/carrot-risotto.html" let result = do val <- extractNextData html nyt <- parseNYTRecipe val pure (nytToCooklang nyt) case result of Nothing -> error "failed to parse/convert carrot-risotto" Just recipe -> do metaTitle (recipeMetadata recipe) `shouldBe` Just "Carrot Risotto With Chile Crisp" metaTotalTime (recipeMetadata recipe) `shouldBe` Just (Duration 30 (Just "minutes")) length (recipeSections recipe) `shouldSatisfy` (> 0) -- | Check if a Maybe value is Just. isJust :: Maybe a -> Bool isJust (Just _) = True isJust Nothing = False