From b14769f7b30675d7e9060bf5ea96d4a4625de065 Mon Sep 17 00:00:00 2001 From: Mark Wotton Date: Fri, 30 Aug 2024 14:04:23 +0700 Subject: [PATCH 1/4] add tasty integration notes --- docs/tasty-integration.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 docs/tasty-integration.md diff --git a/docs/tasty-integration.md b/docs/tasty-integration.md new file mode 100644 index 00000000..9a374cb7 --- /dev/null +++ b/docs/tasty-integration.md @@ -0,0 +1,28 @@ +# using tasty with ghciwatch + +## bubblewrap + +Because `ghciwatch` is waiting for lines to come from `ghci`, if you don't change the buffering, you +can end up waiting forever if you don't change the output buffering from `Tasty`. Something like this works: + +```haskell +module TestMain where + +import Control.Exception (SomeException, try) +import System.IO (BufferMode (NoBuffering), hSetBuffering, stdout) +import Test.Tasty (TestTree, defaultMain, testGroup) + +bubblewrap :: IO () -> IO () +bubblewrap io = do + try io :: IO (Either SomeException ()) + hSetBuffering stdout NoBuffering + +main :: IO () +main = bubblewrap $ defaultMain $ mytestgroup +``` + +## tasty-discover issues + +If you add a new test file, the top level [tasty-discover](https://hackage.haskell.org/package/tasty-discover) +module will not have it set up as a dependency, so will not be reloaded until you restart the `ghciwatch` process. [tasty-autocollect](https://hackage.haskell.org/package/tasty-autocollect) relies on a compiler plugin and seems to avoid +this problem. From 9805df1f3976b30c2bb7ce3f7a8b2a7225408e3d Mon Sep 17 00:00:00 2001 From: Mark Wotton Date: Fri, 30 Aug 2024 14:26:55 +0700 Subject: [PATCH 2/4] fix fractured English --- docs/tasty-integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tasty-integration.md b/docs/tasty-integration.md index 9a374cb7..8eb303b4 100644 --- a/docs/tasty-integration.md +++ b/docs/tasty-integration.md @@ -2,7 +2,7 @@ ## bubblewrap -Because `ghciwatch` is waiting for lines to come from `ghci`, if you don't change the buffering, you +Because `ghciwatch` is waiting for lines to come from `ghci`, you can end up waiting forever if you don't change the output buffering from `Tasty`. Something like this works: ```haskell From af9a3399612c84427abb9f2e00a1697ca0ce4cc9 Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 12 Sep 2024 15:21:30 -0700 Subject: [PATCH 3/4] Rewrite Tasty integration notes for style --- docs/tasty-integration.md | 40 ++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/tasty-integration.md b/docs/tasty-integration.md index 8eb303b4..82595d50 100644 --- a/docs/tasty-integration.md +++ b/docs/tasty-integration.md @@ -1,28 +1,38 @@ -# using tasty with ghciwatch +# Using ghciwatch with tasty -## bubblewrap +Tips and tricks for using ghciwatch with the [Tasty][tasty] test framework. -Because `ghciwatch` is waiting for lines to come from `ghci`, you -can end up waiting forever if you don't change the output buffering from `Tasty`. Something like this works: +[tasty]: https://hackage.haskell.org/package/tasty + +Ghciwatch will wait for GHCi to print output, and it can end up waiting forever +if the Tasty output is buffered. Something like this works: ```haskell module TestMain where -import Control.Exception (SomeException, try) -import System.IO (BufferMode (NoBuffering), hSetBuffering, stdout) +import Control.Exception (bracket) +import System.IO (hGetBuffering, hSetBuffering, stdout) import Test.Tasty (TestTree, defaultMain, testGroup) -bubblewrap :: IO () -> IO () -bubblewrap io = do - try io :: IO (Either SomeException ()) - hSetBuffering stdout NoBuffering +-- | Run an `IO` action, restoring `stdout`\'s buffering mode after the action +-- completes or errors. +protectStdoutBuffering :: IO a -> IO a +protectStdoutBuffering action = + bracket + (hGetBuffering stdout) + (\bufferMode -> hSetBuffering stdout bufferMode) + (const action) main :: IO () -main = bubblewrap $ defaultMain $ mytestgroup +main = protectStdoutBuffering $ defaultMain $ mytestgroup ``` -## tasty-discover issues +## `tasty-discover` issues + +If you add a new test file, you may need to write the top level +[`tasty-discover`][tasty-discover] module to convince ghciwatch to reload it. +[`tasty-autocollect`][tasty-autocollect] relies on a compiler plugin and seems +to avoid this problem. -If you add a new test file, the top level [tasty-discover](https://hackage.haskell.org/package/tasty-discover) -module will not have it set up as a dependency, so will not be reloaded until you restart the `ghciwatch` process. [tasty-autocollect](https://hackage.haskell.org/package/tasty-autocollect) relies on a compiler plugin and seems to avoid -this problem. +[tasty-discover]: https://hackage.haskell.org/package/tasty +[tasty-autocollect]: https://github.com/MercuryTechnologies/ghciwatch/pull/321/files?short_path=c86caa3#diff-c86caa33ad4639b624ef8db59e739295f362bf4c211bed24c8ba484c79af9bdb From 081b28d17e66c0f7c320869da4beaaae87c748fd Mon Sep 17 00:00:00 2001 From: Rebecca Turner Date: Thu, 12 Sep 2024 17:07:41 -0700 Subject: [PATCH 4/4] Add "Integration" section to manual --- docs/SUMMARY.md | 6 +++++- docs/{tasty-integration.md => integration/tasty.md} | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) rename docs/{tasty-integration.md => integration/tasty.md} (97%) diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 655b3f06..442d1b6a 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -1,4 +1,4 @@ -# Summary +# User Manual - [Introduction](./introduction.md) - [Installation](./install.md) @@ -8,3 +8,7 @@ - [Comment evaluation](./comment-evaluation.md) - [Only load modules you need](./no-load.md) - [FAQ](./faq.md) + +# Integration and tips + +- [Tasty](./integration/tasty.md) diff --git a/docs/tasty-integration.md b/docs/integration/tasty.md similarity index 97% rename from docs/tasty-integration.md rename to docs/integration/tasty.md index 82595d50..a6792f68 100644 --- a/docs/tasty-integration.md +++ b/docs/integration/tasty.md @@ -1,4 +1,4 @@ -# Using ghciwatch with tasty +# Tasty Tips and tricks for using ghciwatch with the [Tasty][tasty] test framework.