sydtest 0.29.0.0 → 0.30.0.0
raw patch · 4 files changed
+76/−51 lines, 4 files
Files
- CHANGELOG.md +13/−0
- src/Test/Syd/Def/Scenario.hs +36/−24
- src/Test/Syd/Def/Specify.hs +26/−26
- sydtest.cabal +1/−1
CHANGELOG.md view
@@ -1,5 +1,18 @@ # Changelog +## [0.30.0.0] - 2026-09-02++### Changed++* `scenarioDir`, `scenarioDirRecur` and `scenarioDirOfDirs` take a `Path b Dir`+ and hand the callback a `Path Rel File` or a `Path Rel Dir`, relative to that+ directory, where all three took and gave a `FilePath`.+ Pass `[reldir|test_resources/scenarios|]` for the directory, and join the+ scenario to it to read it.++ Test descriptions are unchanged, so a `--filter` over them still selects the+ same tests.+ ## [0.29.0.0] - 2026-08-19 ### Added
src/Test/Syd/Def/Scenario.hs view
@@ -19,15 +19,20 @@ -- instead, because that usually means the scenario files were omitted by -- accident. --+-- The scenario is given relative to the directory, so it is the name to say the+-- test is about and joining it to the directory is what reads it. Neither has to+-- be recovered from the other.+-- -- Example: ----- > scenarioDir "test_resources/even" $ \fp ->+-- > let dir = [reldir|test_resources/even|]+-- > scenarioDir dir $ \rf -> -- > it "contains an even number" $ do--- > s <- readFile fp+-- > s <- readFile (fromRelFile (dir </> rf)) -- > n <- readIO s -- > (n :: Int) `shouldSatisfy` even-scenarioDir :: FilePath -> (FilePath -> TestDefM outers inner ()) -> TestDefM outers inner ()-scenarioDir = scenarioDirHelper "files" (fmap (map fromRelFile . snd) . listDirRel)+scenarioDir :: Path b Dir -> (Path Rel File -> TestDefM outers inner ()) -> TestDefM outers inner ()+scenarioDir = scenarioDirHelper "files" (fmap snd . listDirRel) -- | Define a test for each file in the given directory, recursively. --@@ -37,13 +42,14 @@ -- -- Example: ----- > scenarioDirRecur "test_resources/odd" $ \fp ->+-- > let dir = [reldir|test_resources/odd|]+-- > scenarioDirRecur dir $ \rf -> -- > it "contains an odd number" $ do--- > s <- readFile fp+-- > s <- readFile (fromRelFile (dir </> rf)) -- > n <- readIO s -- > (n :: Int) `shouldSatisfy` odd-scenarioDirRecur :: FilePath -> (FilePath -> TestDefM outers inner ()) -> TestDefM outers inner ()-scenarioDirRecur = scenarioDirHelper "files" (fmap (map fromRelFile . snd) . listDirRecurRel)+scenarioDirRecur :: Path b Dir -> (Path Rel File -> TestDefM outers inner ()) -> TestDefM outers inner ()+scenarioDirRecur = scenarioDirHelper "files" (fmap snd . listDirRecurRel) -- | Define a test for each subdirectory of the given directory. --@@ -57,32 +63,38 @@ -- -- Example: ----- > scenarioDirOfDirs "test_resources/same" $ \fp ->+-- > let dir = [reldir|test_resources/same|]+-- > scenarioDirOfDirs dir $ \rd -> -- > it "contains two files with the same contents" $ do--- > a <- readFile (fp </> "a")--- > b <- readFile (fp </> "b")+-- > a <- readFile (fromRelFile (dir </> rd </> [relfile|a|]))+-- > b <- readFile (fromRelFile (dir </> rd </> [relfile|b|])) -- > a `shouldBe` b-scenarioDirOfDirs :: FilePath -> (FilePath -> TestDefM outers inner ()) -> TestDefM outers inner ()-scenarioDirOfDirs =- scenarioDirHelper- "directories"- (fmap (map (FP.dropTrailingPathSeparator . fromRelDir) . fst) . listDirRel)+scenarioDirOfDirs :: Path b Dir -> (Path Rel Dir -> TestDefM outers inner ()) -> TestDefM outers inner ()+scenarioDirOfDirs = scenarioDirHelper "directories" (fmap fst . listDirRel) scenarioDirHelper :: -- | What the lister looks for, for the description of the failing test that -- an empty scenario directory produces. String -> -- | The scenarios, relative to the given directory- (Path Abs Dir -> IO [FilePath]) ->- FilePath ->- (FilePath -> TestDefM outers inner ()) ->+ (Path Abs Dir -> IO [Path Rel t]) ->+ Path b Dir ->+ (Path Rel t -> TestDefM outers inner ()) -> TestDefM outers inner ()-scenarioDirHelper noun lister dp func =- describe dp $ do- ad <- liftIO $ resolveDir' dp+scenarioDirHelper noun lister dir func =+ describe (described dir) $ do+ ad <- liftIO $ makeAbsolute dir ss <- liftIO $ fmap (fromMaybe []) $ forgivingAbsence $ lister ad if null ss then it (unwords ["has scenario", noun]) $ \_ ->- (expectationFailure $ unwords ["No scenario", noun, "found in", dp] :: IO ())+ (expectationFailure $ unwords ["No scenario", noun, "found in", described dir] :: IO ()) else forM_ ss $ \s ->- describe s $ func (dp FP.</> s)+ describe (described s) $ func s++-- | A path as a test description.+--+-- The separator a directory's rendering ends in comes off, so that a scenario+-- reads the same whether it is a file or a directory, and so that these+-- descriptions are the ones they were before the scenarios became typed.+described :: Path b t -> String+described = FP.dropTrailingPathSeparator . toFilePath
src/Test/Syd/Def/Specify.hs view
@@ -93,9 +93,9 @@ -- > describe "readFile and writeFile" $ -- > it "reads back what it wrote for this example" $ do -- > let cts = "hello world"--- > let fp = "test.txt"--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = [relfile|test.txt|]+-- > writeFile (fromRelFile file) cts+-- > cts' <- readFile (fromRelFile file) -- > cts' `shouldBe` cts -- --@@ -111,10 +111,10 @@ -- -- > describe "readFile and writeFile" $ -- > it "reads back what it wrote for any example" $ do--- > forAllValid $ \fp ->+-- > forAllValid $ \file -> -- > forAllValid $ \cts -> do--- > writeFile fp cts--- > cts' <- readFile fp+-- > writeFile (fromRelFile file) cts+-- > cts' <- readFile (fromRelFile file) -- > cts' `shouldBe` cts -- --@@ -137,9 +137,9 @@ -- > in around setUpTempDir $ describe "readFile and writeFile" $ -- > it "reads back what it wrote for this example" $ \tempDir -> do -- > let cts = "hello world"--- > let fp = tempDir </> "test.txt"--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = tempDir </> [relfile|test.txt|]+-- > writeFile (fromAbsFile file) cts+-- > cts' <- readFile (fromAbsFile file) -- > cts' `shouldBe` cts -- --@@ -158,9 +158,9 @@ -- > in around setUpTempDir $ describe "readFile and writeFile" $ -- > it "reads back what it wrote for this example" $ \tempDir -> -- > property $ \cts -> do--- > let fp = tempDir </> "test.txt"--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = tempDir </> [relfile|test.txt|]+-- > writeFile (fromAbsFile file) cts+-- > cts' <- readFile (fromAbsFile file) -- > cts' `shouldBe` cts it :: forall outers inner test.@@ -239,9 +239,9 @@ -- > in aroundAll setUpTempDir describe "readFile and writeFile" $ -- > itWithOuter "reads back what it wrote for this example" $ \tempDir -> do -- > let cts = "hello world"--- > let fp = tempDir </> "test.txt"--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = tempDir </> [relfile|test.txt|]+-- > writeFile (fromAbsFile file) cts+-- > cts' <- readFile (fromAbsFile file) -- > cts' `shouldBe` cts -- --@@ -258,11 +258,11 @@ -- -- > let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir -- > in aroundAll setUpTempDir describe "readFile and writeFile" $--- > itWithouter "reads back what it wrote for this example" $ \tempDir ->+-- > itWithOuter "reads back what it wrote for this example" $ \tempDir -> -- > property $ \cts -> do--- > let fp = tempDir </> "test.txt"--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = tempDir </> [relfile|test.txt|]+-- > writeFile (fromAbsFile file) cts+-- > cts' <- readFile (fromAbsFile file) -- > cts' `shouldBe` cts itWithOuter :: (HasCallStack, IsTest test, Arg1 test ~ inner, Arg2 test ~ outer) =>@@ -336,9 +336,9 @@ -- > let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir -- > in aroundAll setUpTempDir describe "readFile and writeFile" $ before (pure "hello world") $ -- > itWithBoth "reads back what it wrote for this example" $ \tempDir cts -> do--- > let fp = tempDir </> "test.txt"--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = tempDir </> [relfile|test.txt|]+-- > writeFile (fromAbsFile file) cts+-- > cts' <- readFile (fromAbsFile file) -- > cts' `shouldBe` cts -- --@@ -354,12 +354,12 @@ -- ===== IO property test -- -- > let setUpTempDir func = withSystemTempDir $ \tempDir -> func tempDir--- > in aroundAll setUpTempDir describe "readFile and writeFile" $ before (pure "test.txt") $+-- > in aroundAll setUpTempDir describe "readFile and writeFile" $ before (pure [relfile|test.txt|]) $ -- > itWithBoth "reads back what it wrote for this example" $ \tempDir fileName -> -- > property $ \cts -> do--- > let fp = tempDir </> fileName--- > writeFile fp cts--- > cts' <- readFile fp+-- > let file = tempDir </> fileName+-- > writeFile (fromAbsFile file) cts+-- > cts' <- readFile (fromAbsFile file) -- > cts' `shouldBe` cts itWithBoth :: ( HasCallStack,
sydtest.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: sydtest-version: 0.29.0.0+version: 0.30.0.0 synopsis: A modern testing framework for Haskell with good defaults and advanced testing features. description: A modern testing framework for Haskell with good defaults and advanced testing features. Sydtest aims to make the common easy and the hard possible. See https://github.com/NorfairKing/sydtest#readme for more information. category: Testing