module Stackctl.Config.RequiredVersionSpec ( spec ) where import Stackctl.Prelude import Data.Version import Stackctl.Config.RequiredVersion import Test.Hspec import Test.QuickCheck spec :: Spec spec = do describe "requiredVersionFromText" $ do it "parses with or without operator" $ do requiredVersionFromText "1.2.3-rc1" `shouldSatisfy` isRight requiredVersionFromText "= 1.2.3-rc1" `shouldSatisfy` isRight it "rejects unknown operators" $ do requiredVersionFromText "!! 1.2.3" `shouldSatisfy` isLeft it "rejects invalid versions" $ do requiredVersionFromText "= wowOMG-2/2" `shouldSatisfy` isLeft describe "parsing operators" $ do let prop cmp = property . uncurry . compareAsRequiredVersion cmp it "compares exactly" $ prop (==) Nothing it "compares with = " $ prop (==) $ Just "=" it "compares with < " $ prop (<) $ Just "<" it "compares with <=" $ prop (<=) $ Just "<=" it "compares with > " $ prop (>) $ Just ">" it "compares with >=" $ prop (>=) $ Just ">=" it "compares with =~" $ prop (=~) $ Just "=~" describe "=~" $ do it "treats equal versions as satisfying" $ do makeVersion [1, 2, 3] =~ makeVersion [1, 2, 3] `shouldBe` True it "treats older versions as non-satisfying" $ do makeVersion [1, 2, 2] =~ makeVersion [1, 2, 3] `shouldBe` False it "treats newer versions of the same branch as satisfying" $ do makeVersion [1, 2, 3, 1] =~ makeVersion [1, 2, 3] `shouldBe` True it "treats newer versions as non-satisfying" $ do makeVersion [1, 2, 4] =~ makeVersion [1, 2, 3] `shouldBe` False it "respects the number of components specified" $ do makeVersion [1, 2] =~ makeVersion [1, 2] `shouldBe` True makeVersion [1, 2, 3] =~ makeVersion [1, 2] `shouldBe` True makeVersion [1, 1] =~ makeVersion [1, 2] `shouldBe` False makeVersion [1, 3] =~ makeVersion [1, 2, 3] `shouldBe` False compareAsRequiredVersion :: (Version -> Version -> Bool) -- ^ Reference compare -> Maybe Text -- ^ Operator -> Version -- ^ Hypothetical required version -> Version -- ^ Hypotehtical current version -> Bool compareAsRequiredVersion cmp mOperator required current = runRequiredVersion mOperator required current == Right (current `cmp` required) runRequiredVersion :: Maybe Text -- ^ Operator -> Version -- ^ Hypothetical required version -> Version -- ^ Hypothetical current version -> Either String Bool runRequiredVersion mOperator required current = (`isRequiredVersionSatisfied` current) <$> requiredVersionFromText rvText where rvText = maybe "" (<> " ") mOperator <> pack (showVersion required)