packages feed

elocrypt 0.3.1 → 0.3.2

raw patch · 5 files changed

+123/−4 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

elocrypt.cabal view
@@ -1,5 +1,5 @@ name:                elocrypt-version:             0.3.1+version:             0.3.2 synopsis:            Generate easy-to-remember, hard-to-guess passwords homepage:            https://www.github.com/sgillespie/elocrypt license:             OtherLicense@@ -9,7 +9,10 @@ copyright:           Copyright: (c) 2015 Sean Gillespie category:            Cryptography build-type:          Simple-extra-source-files:  README.md+extra-source-files:  README.md,+                     test/*.hs,+                     test/Test/*.hs,+                     test/Test/Elocrypt/*.hs cabal-version:       >=1.10  description:@@ -23,7 +26,7 @@ source-repository this   type: git   location: https://github.com/sgillespie/elocrypt.git-  tag: v0.3.0+  tag: v0.3.2                    library   exposed-modules:     Data.Elocrypt,
src/cli/Main.hs view
@@ -10,7 +10,7 @@  import Data.Elocrypt -version = "elocrypt 0.3.1"+version = "elocrypt 0.3.2"  main :: IO () main = do
+ test/Test/Elocrypt/Instances.hs view
@@ -0,0 +1,20 @@+module Test.Elocrypt.Instances where++import Control.Monad+import System.Random+import Test.QuickCheck++instance Arbitrary StdGen where+  arbitrary = mkStdGen `liftM` arbitrary++newtype AlphaChar = Alpha Char+                  deriving (Eq, Ord, Show)++instance Arbitrary AlphaChar where+  arbitrary = Alpha `liftM` elements ['a'..'z']++newtype GreaterThan2 a = GT2 { greaterThan2 :: a }+                       deriving (Eq, Ord, Show)++instance (Num a, Ord a, Arbitrary a) => Arbitrary (GreaterThan2 a) where+  arbitrary = GT2 `fmap` (arbitrary `suchThat` (>2))
+ test/Test/Elocrypt/TrigraphTest.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE TemplateHaskell #-}+module Test.Elocrypt.TrigraphTest where++import Control.Monad+import Test.QuickCheck+import Test.Tasty.QuickCheck (testProperty)+import Test.Tasty.TH++import Test.Elocrypt.Instances+import Data.Elocrypt.Trigraph++tests = $(testGroupGenerator)++prop_findFrequencyShouldSucceedWith2Chars :: AlphaChar -> AlphaChar -> Bool+prop_findFrequencyShouldSucceedWith2Chars (Alpha c1) (Alpha c2)+  = fromJust (findFrequency [c1, c2])+  where fromJust (Just _) = True+        fromJust Nothing  = False++prop_findFrequencyShouldFailWithNot2Chars :: String -> Property+prop_findFrequencyShouldFailWithNot2Chars str+  = length str /= 2 ==> findFrequency str == Nothing
+ test/Test/ElocryptTest.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE TemplateHaskell #-}+module Test.ElocryptTest where++import Control.Monad+import Control.Monad.Random hiding (next)+import Data.Maybe+import System.Random hiding (next)+import Test.QuickCheck+import Test.Tasty.QuickCheck (testProperty)+import Test.Tasty.TH++import Data.Elocrypt+import Data.Elocrypt.Trigraph+import Test.Elocrypt.Instances++tests = $(testGroupGenerator)++prop_genPasswordShouldBeUnique :: GreaterThan2 Int -> StdGen -> Bool+prop_genPasswordShouldBeUnique (GT2 len) gen+  = p /= fst (genPassword len gen')+  where (p, gen') = genPassword len gen++prop_genPasswordsShouldBeUnique :: GreaterThan2 Int -> StdGen -> Bool+prop_genPasswordsShouldBeUnique (GT2 len) gen+  = p /= ps+  where (p:ps:_) = fst (genPasswords len gen)++prop_newPasswordShouldBeLength :: GreaterThan2 Int -> StdGen -> Bool+prop_newPasswordShouldBeLength (GT2 len) gen = length (newPassword len gen) == len++prop_newPasswordShouldConsistOfAlphabet :: GreaterThan2 Int -> StdGen -> Bool+prop_newPasswordShouldConsistOfAlphabet (GT2 len) gen+  = all ((flip elem) alphabet) (newPassword len gen)++prop_newPasswordsShouldBeUnique :: GreaterThan2 Int -> StdGen -> Bool+prop_newPasswordsShouldBeUnique (GT2 len) gen+  = p /= ps+  where (p:ps:_) = newPasswords len gen++prop_first2ShouldHaveLength2 :: StdGen -> Bool+prop_first2ShouldHaveLength2 g = length (evalRand first2 g) == 2++prop_nextShouldSkip0Weights :: AlphaChar -> AlphaChar -> StdGen -> Property+prop_nextShouldSkip0Weights (Alpha c1) (Alpha c2) gen = isCandidate next' [c1, c2]+  where next' = evalRand (next . reverse $ [c1, c2]) gen++prop_lastNShouldSkip0Weights :: AlphaChar -> AlphaChar -> Int -> StdGen -> Property+prop_lastNShouldSkip0Weights (Alpha c1) (Alpha c2) len gen+  = len > 0 ==> lastNShouldSkip0Weights' lastN'+  where f2 = [c1, c2]+        lastN' = evalRand (lastN (reverse [c1, c2]) len) gen++lastNShouldSkip0Weights' :: String -> Property+lastNShouldSkip0Weights' (p:ps:pss:psss) = isCandidate p [pss, ps] .&&.+                                           lastNShouldSkip0Weights' (ps:pss:psss)+lastNShouldSkip0Weights' _ = property True++-- Utility functions+isCandidate :: Char -> String -> Property+isCandidate c (s:ss:sss) = hasCandidates f2 ==>+                           isJust $ elem c `liftM` findNextCandidates f2+  where f2 = [s, ss]++isCandidate _ _ = undefined -- This really shouldn't ever happen++hasCandidates :: String -> Bool+hasCandidates s = (not . null) `liftM` findNextCandidates s == Just True++findNextCandidates :: String -> Maybe [Char]+findNextCandidates (c1:c2:_) = map fst `liftM` frequency+  where f2 = [c1, c2]+        frequency = (filter ((/=0) . snd) . zip ['a'..'z']) `liftM` findFrequency f2++findNextCandidates _ = Nothing  -- This really shouldn't ever happen