diff --git a/doctests.hs b/doctests.hs index 300898f6..72e3b8a1 100644 --- a/doctests.hs +++ b/doctests.hs @@ -2,13 +2,27 @@ module Main where import Build_doctests (flags, pkgs, module_sources) import Data.Foldable (traverse_) -import System.Environment.Compat (unsetEnv) +import System.Environment.Compat (getArgs, unsetEnv) import Test.DocTest (doctest) +import qualified Data.List as List + main :: IO () main = do + cliArgs <- getArgs + let (cliArgs1, mods) = + if (List.null (filter (== "--modules") cliArgs)) + then (cliArgs, module_sources) + else (List.delete "--modules" cliArgs, []) + let args = + [ "-outputdir=./_doctests/" + , "-fobject-code" + , "--fast" + ] + ++ cliArgs1 + ++ flags + ++ pkgs + ++ mods traverse_ putStrLn args unsetEnv "GHC_ENVIRONMENT" doctest args - where - args = flags ++ ["-outputdir=./_doctests/", "-fobject-code"] ++ pkgs ++ module_sources diff --git a/src/Streamly/Internal/Data/Stream/Ahead.hs b/src/Streamly/Internal/Data/Stream/Ahead.hs index 84ae32f7..93a57808 100644 --- a/src/Streamly/Internal/Data/Stream/Ahead.hs +++ b/src/Streamly/Internal/Data/Stream/Ahead.hs @@ -619,7 +619,7 @@ infixr 6 `ahead` -- original streams, side effects will happen in the order in which the streams -- are evaluated: -- --- >>> import Streamly.Prelude (ahead) +-- >>> import Streamly.Prelude (ahead, SerialT) -- >>> stream1 = Stream.fromEffect (delay 4) :: SerialT IO Int -- >>> stream2 = Stream.fromEffect (delay 2) :: SerialT IO Int -- >>> Stream.toList $ stream1 `ahead` stream2 :: IO [Int] diff --git a/src/Streamly/Internal/Data/Stream/Serial.hs b/src/Streamly/Internal/Data/Stream/Serial.hs index 2d3283fe..ed10bdf2 100644 --- a/src/Streamly/Internal/Data/Stream/Serial.hs +++ b/src/Streamly/Internal/Data/Stream/Serial.hs @@ -281,6 +281,7 @@ TRAVERSABLE_INSTANCE(SerialT) -- element @1@ in the first stream with all the nested iterations of element -- @2@: -- +-- >>> import Streamly.Prelude (wSerial) -- >>> Stream.toList $ Stream.fromList [(1,3),(1,4)] `wSerial` Stream.fromList [(2,3),(2,4)] -- [(1,3),(2,3),(1,4),(2,4)] -- diff --git a/test/README.md b/test/README.md index d7ee4600..af59bd52 100644 --- a/test/README.md +++ b/test/README.md @@ -1,4 +1,6 @@ -## Using bin/test.sh +# Streamly Tests + +## Running tests using bin/test.sh `bin/test.sh` (path relative to the top level repo dir) can run selected test groups, generate coverage report, pass GHC RTS options when @@ -15,7 +17,9 @@ To view coverage report, open `./hpc_index.html` in browser. See `bin/test.sh --help` for more info. -## Build a single test +## Building and Running Tests using cabal + +### Build a single test ``` $ cabal build test:Prelude.Serial @@ -33,7 +37,7 @@ Build with optimizations: $ cabal build --flag opt ... ``` -## Build all tests +### Build all tests ``` $ cabal build --enable-tests all @@ -51,7 +55,7 @@ Or this, note this command does not work as expected when in the "test" dir: $ cabal build --enable-tests streamly-tests ``` -## Build and run +### Build and run Running all test suites, use any of the following: @@ -71,7 +75,7 @@ Or this, note this command does not work as expected when in the "test" dir: $ cabal test streamly-tests ``` -## Build and Run a single test suite +### Build and Run a single test suite To run `Prelude.Serial` test-suite: @@ -88,6 +92,63 @@ $ cd test; cabal run Prelude.Serial Note you could use `cabal test Prelude.Serial` but that unfortunately builds all the test suites before running `Prelude.Serial`. +## Writing doctests + +* The test named `doctest` runs all the code snippets in a source module + that are written using the `>>>` markup in haddock. See `doctest.hs`. +* Make sure you do not enclose your snippets in the `@ .. @` markup otherwise + they will show up verbatim in the docs and not as ghci styled snippets. +* We use `--fast` mode of doctest, which means snippets are run as if you are + typing those examples from top to bottom in that order in GHCi. Previous + snippet's state is available to the next one. +* A haddock section named `$setup` contains a snippet that is always run before + any other. When `--fast` mode is not used it is run before every snippet. + +An example setup section: + +``` +-- $setup +-- >>> :m +-- >>> import Control.Monad.IO.Class (MonadIO(..)) +-- >>> import Data.Function ((&)) +``` + +Some tests that may take long can be written as follows. Just assigning +the code to a function makes it compile but not run. + +``` +>>> :{ +main = do + Stream.drain $ Stream.fromAsync $ foldMap delay [1..10] + Stream.drain $ Stream.concatFoldableWith Stream.async (map delay [1..10]) + Stream.drain $ Stream.concatMapFoldableWith Stream.async delay [1..10] + Stream.drain $ Stream.concatForFoldableWith Stream.async [1..10] delay +:} +``` + +## Running doctests + +Run tests for all modules: + +``` +$ cabal run doctests --flag doctests +``` + +Use verbose mode to debug: + +``` +$ cabal run doctests --flag doctests -- --verbose +``` + +Run tests only for selected modules: + +``` +$ cabal run doctests --flag doctests -- --modules Streamly.Prelude +``` + +If it fails with a message that a particular modules is not loaded specify that +module as well on the command line. + ## Naming of test modules Tests are organized by source modules. For example, for the source