diff --git a/WORKSPACE b/WORKSPACE index b75ec7f43c..498c2140d5 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -102,7 +102,6 @@ stack_snapshot( "hspec", "hspec-core", "hspec-expectations", - "leancheck", "lens", "network", "network-uri", diff --git a/semantic/BUILD.bazel b/semantic/BUILD.bazel index fae0d08468..a3eb0f1114 100644 --- a/semantic/BUILD.bazel +++ b/semantic/BUILD.bazel @@ -169,7 +169,6 @@ haskell_test( "@stackage//:hspec", "@stackage//:hspec-core", "@stackage//:hspec-expectations", - "@stackage//:leancheck", "@stackage//:tasty", "@stackage//:tasty-golden", "@stackage//:tasty-hedgehog", diff --git a/semantic/semantic.cabal b/semantic/semantic.cabal index 83822e2eb9..f1c6841eaa 100644 --- a/semantic/semantic.cabal +++ b/semantic/semantic.cabal @@ -198,8 +198,7 @@ test-suite test type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs - other-modules: Data.Functor.Listable - , Data.Graph.Spec + other-modules: Data.Graph.Spec , Data.Language.Spec , Data.Semigroup.App.Spec , Integration.Spec @@ -209,7 +208,6 @@ test-suite test , Semantic.Stat.Spec , Tags.Spec , SpecHelpers - , Test.Hspec.LeanCheck , Generators , Properties build-depends: semantic @@ -228,7 +226,6 @@ test-suite test , tasty-hspec ^>= 1.1.5.1 , tasty-hunit ^>= 0.10.0.2 , HUnit ^>= 1.6.0.0 - , leancheck >= 0.8 && <1 , temporary ^>= 1.3 test-suite parse-examples diff --git a/semantic/test/Data/Functor/Listable.hs b/semantic/test/Data/Functor/Listable.hs deleted file mode 100644 index 5250a0b2a0..0000000000 --- a/semantic/test/Data/Functor/Listable.hs +++ /dev/null @@ -1,112 +0,0 @@ -{-# LANGUAGE DataKinds, FlexibleContexts, FlexibleInstances, ScopedTypeVariables, TypeOperators #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} -module Data.Functor.Listable -( Listable(..) -, mapT -, cons0 -, cons1 -, cons2 -, cons3 -, cons4 -, cons5 -, cons6 -, (\/) -, addWeight -, ofWeight -) where - -import qualified Analysis.Name as Name -import Data.Bifunctor.Join -import Data.Edit -import qualified Data.Language as Language -import Data.List.NonEmpty -import Data.Text as T (Text, pack) -import Source.Loc -import Source.Span -import Test.LeanCheck - -type Tier a = [a] - --- | Lifting of 'Listable' to @* -> *@. -class Listable1 l where - -- | The tiers for @l :: * -> *@, parameterized by the tiers for @a :: *@. - liftTiers :: [Tier a] -> [Tier (l a)] - --- | Lifting of 'Listable' to @* -> * -> *@. -class Listable2 l where - -- | The tiers for @l :: * -> * -> *@, parameterized by the tiers for @a :: *@ & @b :: *@. - liftTiers2 :: [Tier a] -> [Tier b] -> [Tier (l a b)] - --- | A suitable definition of 'tiers' for 'Listable2' type constructors parameterized by 'Listable' types. -tiers2 :: (Listable a, Listable b, Listable2 l) => [Tier (l a b)] -tiers2 = liftTiers2 tiers tiers - - --- | Lifts a unary constructor to a list of tiers, given a list of tiers for its argument. --- --- Commonly used in the definition of 'Listable1' and 'Listable2' instances. -liftCons1 :: [Tier a] -> (a -> b) -> [Tier b] -liftCons1 tiers f = mapT f tiers `addWeight` 1 - --- | Lifts a binary constructor to a list of tiers, given lists of tiers for its arguments. --- --- Commonly used in the definition of 'Listable1' and 'Listable2' instances. -liftCons2 :: [Tier a] -> [Tier b] -> (a -> b -> c) -> [Tier c] -liftCons2 tiers1 tiers2 f = mapT (uncurry f) (liftTiers2 tiers1 tiers2) `addWeight` 1 - --- Instances - -instance Listable1 Maybe where - liftTiers tiers = cons0 Nothing \/ liftCons1 tiers Just - -instance Listable2 (,) where - liftTiers2 = (><) - -instance Listable2 Either where - liftTiers2 leftTiers rightTiers = liftCons1 leftTiers Left \/ liftCons1 rightTiers Right - -instance Listable a => Listable1 ((,) a) where - liftTiers = liftTiers2 tiers - -instance Listable1 [] where - liftTiers tiers = go - where go = cons0 [] \/ liftCons2 tiers go (:) - -instance Listable1 NonEmpty where - liftTiers tiers = liftCons2 tiers (liftTiers tiers) (:|) - -instance Listable2 p => Listable1 (Join p) where - liftTiers tiers = liftCons1 (liftTiers2 tiers tiers) Join - -instance Listable2 Edit where - liftTiers2 t1 t2 = liftCons1 t2 Insert \/ liftCons1 t1 Delete \/ liftCons2 t1 t2 Compare - -instance (Listable a, Listable b) => Listable (Edit a b) where - tiers = tiers2 - - -instance Listable Name.Name where - tiers = cons1 Name.name - -instance Listable Text where - tiers = pack `mapT` tiers - -instance Listable Language.Language where - tiers - = cons0 Language.Go - \/ cons0 Language.JavaScript - \/ cons0 Language.Python - \/ cons0 Language.Ruby - \/ cons0 Language.TypeScript - -instance Listable Loc where - tiers = cons2 Loc - -instance Listable Range where - tiers = cons2 Range - -instance Listable Pos where - tiers = cons2 Pos - -instance Listable Span where - tiers = cons2 Span diff --git a/semantic/test/SpecHelpers.hs b/semantic/test/SpecHelpers.hs index 545e857589..7234f33378 100644 --- a/semantic/test/SpecHelpers.hs +++ b/semantic/test/SpecHelpers.hs @@ -32,7 +32,6 @@ import Data.ByteString.Builder (Builder, toLazyByteString) import Data.ByteString.Lazy (toStrict) import Data.Edit as X import Data.Foldable (toList) -import Data.Functor.Listable as X import Data.Language as X hiding (Precise) import Data.List.NonEmpty as X (NonEmpty (..)) import Data.Maybe as X @@ -56,8 +55,6 @@ import System.Exit (die) import qualified System.Path as Path import Test.Hspec as X (Spec, SpecWith, around, context, describe, it, parallel, pendingWith, runIO, xit) import Test.Hspec.Expectations as X -import Test.Hspec.LeanCheck as X -import Test.LeanCheck as X instance Lower X.Span where lowerBound = Source.Span.point (Pos 1 1) diff --git a/semantic/test/Test/Hspec/LeanCheck.hs b/semantic/test/Test/Hspec/LeanCheck.hs deleted file mode 100644 index d9e1f52844..0000000000 --- a/semantic/test/Test/Hspec/LeanCheck.hs +++ /dev/null @@ -1,93 +0,0 @@ -{-# LANGUAGE FlexibleInstances, GADTs, TypeFamilies #-} -module Test.Hspec.LeanCheck -( prop -, forAll -) where - -import Control.Exception -import Data.Bifunctor (first) -import Data.List (intercalate) -import Data.Maybe (listToMaybe) -import Test.Hspec -import Test.Hspec.Core.Spec as Hspec -import qualified Test.HUnit.Lang as HUnit -import Test.LeanCheck.Core - -data Property where - Property :: IOTestable prop => prop -> Property - --- | Perform an enumerative test of a property using LeanCheck. --- --- 'prop' will typically be a function of one or more 'Listable' arguments, returning either 'Bool' or 'IO ()' (in the latter case, typically via 'shouldBe' and friends). For example: --- --- > describe "+" $ do --- > prop "associativity" $ --- > \ a b c -> a + (b + c) `shouldBe` (a + b :: Int) + c -prop :: (HasCallStack, IOTestable prop) => String -> prop -> Spec -prop s = it s . Property - -data ForAll a where - ForAll :: IOTestable prop => [[a]] -> (a -> prop) -> ForAll a - --- | Test a property given by an explicit list of tiers rather than a 'Listable' instance. This can be used to e.g. filter input values for which the property does not hold. --- --- > describe "mean" $ do --- > prop "≥ the minimum" . forAll (not . null `filterT` tiers) $ --- > \ list -> (mean list :: Int) `shouldSatisfy` (>= min list) -forAll :: IOTestable prop => [[a]] -> (a -> prop) -> ForAll a -forAll = ForAll - -instance Example Property where - type Arg Property = () - evaluateExample (Property prop) (Params _ bound) _ _ = do - result <- try (iocounterExample bound prop) - case result of - Left e - | Just (LeanCheckException messages e') <- fromException e -> throw (addMessages messages e') - | otherwise -> throw e - Right (Just messages) -> pure $ Result "" (Failure Nothing (Reason (concat messages))) - Right Nothing -> pure $ Result "" Success - where addMessages messages (HUnit.HUnitFailure loc r) = HUnit.HUnitFailure loc $ case r of - HUnit.Reason s -> HUnit.Reason (intercalate "\n" messages ++ "\n" ++ s) - HUnit.ExpectedButGot Nothing expected actual -> HUnit.ExpectedButGot (Just (concat messages)) expected actual - HUnit.ExpectedButGot (Just preface) expected actual -> HUnit.ExpectedButGot (Just (intercalate "\n" messages ++ preface)) expected actual - - -class IOTestable t where - -- 'resultiers', lifted into 'IO'. - ioResultTiers :: t -> [[IO ([String], Bool)]] - -instance IOTestable (IO ()) where - ioResultTiers action = [[ (action >> pure ([], True)) `catch` (throw . LeanCheckException []) ]] - -instance (IOTestable b, Show a, Listable a) => IOTestable (a -> b) where - ioResultTiers p = concatMapT (resultiersFor p) tiers - -instance IOTestable Bool where - ioResultTiers p = [[ pure ([], p) ]] - -instance Show a => IOTestable (ForAll a) where - ioResultTiers (ForAll tiers property) = concatMapT (resultiersFor property) tiers - -resultiersFor :: (IOTestable b, Show a) => (a -> b) -> a -> [[IO ([String], Bool)]] -resultiersFor p x = fmap (eval x) <$> ioResultTiers (p x) - -eval :: Show a => a -> IO ([String], Bool) -> IO ([String], Bool) -eval x action = first (prepend x) <$> action - `catch` \ (LeanCheckException messages failure) -> throw (LeanCheckException (prepend x messages) failure) - where prepend x = (showsPrec 11 x "":) - - --- | 'counterExamples', lifted into 'IO'. -iocounterExamples :: IOTestable a => Int -> a -> IO [[String]] -iocounterExamples n = fmap (fmap fst . filter (not . snd)) . sequenceA . take n . concat . ioResultTiers - --- | 'counterExample', lifted into 'IO'. -iocounterExample :: IOTestable a => Int -> a -> IO (Maybe [String]) -iocounterExample n = fmap listToMaybe . iocounterExamples n - - -data LeanCheckException = LeanCheckException [String] HUnit.HUnitFailure - deriving (Show) - -instance Exception LeanCheckException