Phase 4: Recipe references + all 4 example file validation
- Fix pRecipeRef to include ./ prefix in stored path - Add recipe reference test - Add parse-validation tests for all 4 example .cook files (EasyPancakes, FriedRice, CoffeeSouffle, OlivierSalad) - All 24 tests passing, all examples parse without error
This commit is contained in:
+2
-1
@@ -131,11 +131,12 @@ pLineBreak = do
|
||||
pRecipeRef :: Parser StepItem
|
||||
pRecipeRef = do
|
||||
_ <- P.char '@'
|
||||
-- Consume @ and store ./ as part of the path
|
||||
_ <- P.char '.'
|
||||
_ <- P.char '/'
|
||||
path <- P.many (P.noneOf "{(\n\\")
|
||||
mqty <- P.optionMaybe (P.between (P.char '{') (P.char '}') pQuantityBody)
|
||||
return (StepRecipeRef (RecipeRef path (join mqty)))
|
||||
return (StepRecipeRef (RecipeRef ("./" <> path) (join mqty)))
|
||||
|
||||
-- | Ingredient: @name{quantity%unit}(preparation)
|
||||
pIngredient :: Parser StepItem
|
||||
|
||||
@@ -2,6 +2,7 @@ module Roux.ParserSpec (spec) where
|
||||
|
||||
import Data.List.NonEmpty (NonEmpty ((:|)))
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
import qualified Data.Text.IO as TIO
|
||||
import Test.Hspec (Spec, describe, expectationFailure, it, shouldBe)
|
||||
|
||||
import Roux.Parser (parseCookFile)
|
||||
@@ -369,3 +370,44 @@ spec = do
|
||||
_ ->
|
||||
expectationFailure
|
||||
("expected SecStep as third body item, got body=" <> show body)
|
||||
|
||||
describe "Recipe references" $ do
|
||||
it "parses a recipe reference" $ do
|
||||
let input = "Pour over with @./sauces/Hollandaise{150%g}."
|
||||
case parseCookFile input of
|
||||
Left err -> expectationFailure ("parse failed: " <> err)
|
||||
Right recipe -> do
|
||||
let items = stepItems recipe
|
||||
let expected =
|
||||
[ StepText "Pour over with "
|
||||
, StepRecipeRef (RecipeRef "./sauces/Hollandaise" (Just (Quantity 150 (Just "g") False)))
|
||||
, StepText "."
|
||||
]
|
||||
items `shouldBe` expected
|
||||
|
||||
describe "Full recipe files" $ do
|
||||
let readExample name = do
|
||||
content <- TIO.readFile ("cooklang-examples/" <> name <> ".cook")
|
||||
case parseCookFile content of
|
||||
Left err -> expectationFailure (name <> ": " <> err)
|
||||
Right _ -> pure ()
|
||||
|
||||
it "EasyPancakes parses without error" $ do
|
||||
readExample "EasyPancakes"
|
||||
|
||||
it "FriedRice parses without error" $ do
|
||||
readExample "FriedRice"
|
||||
|
||||
it "CoffeeSouffle parses without error" $ do
|
||||
readExample "CoffeeSouffle"
|
||||
|
||||
it "OlivierSalad parses without error" $ do
|
||||
readExample "OlivierSalad"
|
||||
|
||||
-- | Extract step items from the first step of an unnamed section.
|
||||
stepItems :: Recipe -> [StepItem]
|
||||
stepItems r =
|
||||
let s = NE.head (recipeSections r)
|
||||
in case NE.head (sectionBody s) of
|
||||
SecStep step -> unStep step
|
||||
_ -> []
|
||||
|
||||
Reference in New Issue
Block a user