tasty-focus (empty) → 1.0.0
raw patch · 6 files changed
+211/−0 lines, 6 filesdep +basedep +taggeddep +tasty
Dependencies added: base, tagged, tasty, tasty-expected-failure, tasty-focus, tasty-hunit
Files
- CHANGELOG.md +6/−0
- LICENSE +29/−0
- README.md +25/−0
- src/Test/Tasty/Focus.hs +54/−0
- tasty-focus.cabal +44/−0
- test/Spec.hs +53/−0
+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Changelog++## 1.0.0++### [Added]+- Initial version
+ LICENSE view
@@ -0,0 +1,29 @@+BSD 3-Clause License++Copyright (c) 2020, Jonas Carpay+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+ contributors may be used to endorse or promote products derived from+ this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,25 @@+## tasty-focus++Simple focus mechanism for `tasty`, similar to `hspec`.++Mark the root of your test tree with `withFocus`.+Then, if any of the subtrees of your test suite are marked with `focus`, only those test trees will be run.++The intended use case is similar to `--pattern`, but for quick `ghcid`-based feedback loops.+Using `focus` will throw a deprecation warning, so that together with `-Werror` you can check that you don't accidentally leave tests focused on CI.++### Example+In this example, only `barTests` will run. Removing either `focus` or `withFocus` will run the entire tree again.++```haskell+main :: IO ()+main = defaultMain . withFocus $+ testGroup "tests"+ [ fooTests+ , testGroup "subgroup"+ [ focus barTests+ , bazTests+ ]+ , quuxTests+ ]+```
+ src/Test/Tasty/Focus.hs view
@@ -0,0 +1,54 @@+-- | Simple focus mechanism for @tasty@, similar to @hspec@.+-- Mark the root of your test tree with 'withFocus'.+-- Then, if any of the subtrees of your test suite are marked with 'focus', only those test trees will be run.+module Test.Tasty.Focus+ ( withFocus,+ focus,+ )+where++import Data.Monoid+import Data.Tagged+import Test.Tasty+import Test.Tasty.Options+import Test.Tasty.Runners++data Focused = Focused | NotFocused++instance IsOption Focused where+ defaultValue = NotFocused+ parseValue _ = Nothing+ optionName = Tagged "focused"+ optionHelp = Tagged "focused"++anyFocused :: TestTree -> Bool+anyFocused = getAny . foldTestTree tfold mempty+ where+ tfold = trivialFold {foldSingle = \opts _ _ -> Any (focusedOpts opts)}+ focusedOpts opts = case lookupOption opts of+ Focused -> True+ NotFocused -> False++{-# WARNING focus "Focusing tests... don't forget to re-enable your entire test suite!" #-}++-- | Intended to be used at the root of your test suite.+-- If any of the subtrees are focused, filter out all non-focused subtrees.+-- If there are no focused subtrees, return the entire tree.+withFocus :: TestTree -> TestTree+withFocus tree = if anyFocused tree then go tree else tree+ where+ go (PlusTestOptions f t) = case lookupOption (f mempty) of+ NotFocused -> TestGroup "ignored" []+ Focused -> PlusTestOptions f t+ go (TestGroup n t) = TestGroup n (fmap go . filter anyFocused $ t)+ go (SingleTest n t) = SingleTest n t+ go (WithResource s k) = WithResource s (go . k)+ go (AskOptions f) = AskOptions (go . f)+ go (After d e t) = After d e (go t)++-- | Marks the tree as focused, as long as none of its subtrees are focused.+focus :: TestTree -> TestTree+focus tree =+ if anyFocused tree+ then tree+ else testGroup "focused" [PlusTestOptions (setOption Focused) tree]
+ tasty-focus.cabal view
@@ -0,0 +1,44 @@+cabal-version: 2.4+name: tasty-focus+version: 1.0.0+license: BSD-3-Clause+build-type: Simple+license-file: LICENSE+author: Jonas Carpay+maintainer: Jonas Carpay <jonascarpay@gmail.com>+copyright: 2020 Jonas Carpay+tested-with: GHC ==8.10.2+synopsis: Simple focus mechanism for tasty+description: Simple focus mechanism for tasty, similar to hspec.+extra-doc-files:+ CHANGELOG.md+ README.md++common common-options+ build-depends: base >=4.9 && <5+ default-language: Haskell2010+ ghc-options:+ -Wall -Wcompat -Widentities -Wincomplete-uni-patterns+ -Wincomplete-record-updates -Wredundant-constraints+ -fhide-source-paths -Wpartial-fields++library+ import: common-options+ hs-source-dirs: src+ exposed-modules: Test.Tasty.Focus+ build-depends:+ , tagged+ , tasty++test-suite tasty-focus-test+ import: common-options+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ build-depends:+ , tasty+ , tasty-expected-failure+ , tasty-focus+ , tasty-hunit++ ghc-options: -threaded -rtsopts -with-rtsopts=-N
+ test/Spec.hs view
@@ -0,0 +1,53 @@+import Test.Tasty.Focus+import Test.Tasty.ExpectedFailure+import Test.Tasty+import Test.Tasty.HUnit++failure :: TestTree+failure = testCase "failure" $ assertFailure "test failure"++success :: TestTree+success = testCase "success" $ pure ()++main :: IO ()+main =+ defaultMain $+ testGroup+ "tasty-focus"+ [ expectFail . withFocus $+ testGroup+ "no focus runs everything"+ [ failure+ ],+ expectFail . withFocus . focus $+ testGroup+ "focus entire tree runs everything"+ [ failure+ ],+ withFocus $+ testGroup+ "focus out failure"+ [ focus success,+ failure+ ],+ withFocus $+ testGroup+ "deep focus"+ [ testGroup+ "nest"+ [ focus success,+ failure+ ],+ failure+ ],+ withFocus . focus $+ testGroup+ "nested focus precedence"+ [ testGroup+ "nest"+ [ focus success,+ failure+ ],+ failure+ ]+ ]