packages feed

skeletest-0.3.0: test/Skeletest/Internal/TestTargetsSpec.hs

{-# LANGUAGE OverloadedStrings #-}

module Skeletest.Internal.TestTargetsSpec (spec) where

import Skeletest
import Skeletest.Internal.TestTargets
import Skeletest.Predicate qualified as P

spec :: Spec
spec = do
  describe "matchesTest" $ do
    let someAttrs =
          TestAttrs
            { testPath = "MyTestSpec.hs"
            , testIdentifier = ["a", "b", "test name"]
            , testMarkers = ["mark1", "mark2"]
            }

    sequence_
      [ it label $
          matchesTest selection attrs `shouldBe` True
      | (label, selection, attrs) <-
          [
            ( "matches any test"
            , TestTargetEverything
            , someAttrs
            )
          ,
            ( "matches tests in file"
            , TestTargetFile "FooSpec.hs"
            , someAttrs{testPath = "FooSpec.hs"}
            )
          ,
            ( "matches test name substring"
            , TestTargetName "foo"
            , someAttrs{testIdentifier = ["group1", "group2", "my foo test"]}
            )
          ,
            ( "matches group name substring"
            , TestTargetName "fooFunc"
            , someAttrs{testIdentifier = ["fooFunction", "does a thing"]}
            )
          ,
            ( "matches a marker exactly"
            , TestTargetMarker "fast"
            , someAttrs{testMarkers = ["fast", "slow"]}
            )
          ,
            ( "matches a NOT target when target does not match"
            , TestTargetNot (TestTargetFile "FooSpec.hs")
            , someAttrs{testPath = "BarSpec.hs"}
            )
          ,
            ( "matches an AND target when target matches both"
            , TestTargetAnd (TestTargetFile "FooSpec.hs") (TestTargetMarker "fast")
            , someAttrs{testPath = "FooSpec.hs", testMarkers = ["fast"]}
            )
          ,
            ( "matches an OR target when target matches one"
            , TestTargetOr (TestTargetFile "FooSpec.hs") (TestTargetMarker "fast")
            , someAttrs{testPath = "FooSpec.hs", testMarkers = []}
            )
          ]
      ]

    sequence_
      [ it label $
          matchesTest selection attrs `shouldBe` False
      | (label, selection, attrs) <-
          [
            ( "does not match test in another file"
            , TestTargetFile "FooSpec.hs"
            , someAttrs{testPath = "BarSpec.hs"}
            )
          ,
            ( "does not match test not containing name"
            , TestTargetName "foo"
            , someAttrs{testIdentifier = ["group1", "group2", "other test"]}
            )
          ,
            ( "does not match marker substring"
            , TestTargetMarker "fastish"
            , someAttrs{testMarkers = ["fast"]}
            )
          ,
            ( "does not match a NOT target when target matches"
            , TestTargetNot (TestTargetFile "FooSpec.hs")
            , someAttrs{testPath = "FooSpec.hs"}
            )
          ,
            ( "does not match an AND target when target does not match one"
            , TestTargetAnd (TestTargetFile "FooSpec.hs") (TestTargetMarker "fast")
            , someAttrs{testPath = "BarSpec.hs", testMarkers = ["fast"]}
            )
          ,
            ( "does not match an OR target when target does not match either"
            , TestTargetOr (TestTargetFile "FooSpec.hs") (TestTargetMarker "fast")
            , someAttrs{testPath = "BarSpec.hs", testMarkers = []}
            )
          ]
      ]

  describe "parseTestTargets" $ do
    sequence_
      [ it label $
          parseTestTargets input `shouldBe` Right (Just expected)
      | (label, input, expected) <-
          [
            ( "parses everything"
            , ["*"]
            , TestTargetEverything
            )
          ,
            ( "parses file name"
            , ["test/MyLib/FooSpec.hs"]
            , TestTargetFile "test/MyLib/FooSpec.hs"
            )
          ,
            ( "parses test name"
            , ["[test]"]
            , TestTargetName "test"
            )
          ,
            ( "parses test name with spaces"
            , ["[foo test]"]
            , TestTargetName "foo test"
            )
          ,
            ( "parses test marker"
            , ["@fast"]
            , TestTargetMarker "fast"
            )
          ,
            ( "parses file name with test name"
            , ["test/FooSpec.hs[fooFunc]"]
            , TestTargetAnd (TestTargetFile "test/FooSpec.hs") (TestTargetName "fooFunc")
            )
          ,
            ( "parses not operations"
            , ["not [fooFunc]"]
            , TestTargetNot (TestTargetName "fooFunc")
            )
          ,
            ( "parses and operations between test names"
            , ["[fooFunc] and [barFunc]"]
            , TestTargetAnd (TestTargetName "fooFunc") (TestTargetName "barFunc")
            )
          ,
            ( "parses and operations between markers"
            , ["@foo and @fast"]
            , TestTargetAnd (TestTargetMarker "foo") (TestTargetMarker "fast")
            )
          ,
            ( "parses or operations between test names"
            , ["[fooFunc] or [barFunc]"]
            , TestTargetOr (TestTargetName "fooFunc") (TestTargetName "barFunc")
            )
          ,
            ( "parses or operations between markers"
            , ["@foo or @fast"]
            , TestTargetOr (TestTargetMarker "foo") (TestTargetMarker "fast")
            )
          ,
            ( "parses or operations between files"
            , ["FooSpec.hs or BarSpec.hs"]
            , TestTargetOr (TestTargetFile "FooSpec.hs") (TestTargetFile "BarSpec.hs")
            )
          ,
            ( "joins multiple targets with or"
            , ["[fooFunc]", "test/BarSpec.hs"]
            , TestTargetOr (TestTargetName "fooFunc") (TestTargetFile "test/BarSpec.hs")
            )
          ,
            ( "parses multiple binary operations"
            , ["[a] or [b] and [c] or [d]"]
            , TestTargetOr
                ( TestTargetAnd
                    (TestTargetOr (TestTargetName "a") (TestTargetName "b"))
                    (TestTargetName "c")
                )
                (TestTargetName "d")
            )
          ,
            ( "parses parenthesized expressions"
            , ["([a] or [b]) and ([c] or [d])"]
            , TestTargetAnd
                (TestTargetOr (TestTargetName "a") (TestTargetName "b"))
                (TestTargetOr (TestTargetName "c") (TestTargetName "d"))
            )
          ]
      ]

    it "fails with a helpful error message" $
      parseTestTargets ["test/Example!Spec.hs"] `shouldSatisfy` P.left P.matchesSnapshot