1import Control.Monad (replicateM)
3import qualified Data.ByteString.Lazy as B
5import Data.List (nub, (\\))
8import qualified Data.UUID as U
9import qualified Data.UUID.V1 as U
10import qualified Data.UUID.V5 as U
17isValidVersion :: Int -> U.UUID -> Bool
18isValidVersion v u = lenOK && variantOK && versionOK
19 where bs = U.toByteString u
20 lenOK = B.length bs == 16
21 variantOK = (B.index bs 8) .&. 0xc0 == 0x80
22 versionOK = (B.index bs 6) .&. 0xf0 == fromIntegral (v `shiftL` 4)
25instance Arbitrary U.UUID where
26 arbitrary = (fst . random) `fmap` rand
27 coarbitrary = undefined
29instance Arbitrary Word8 where
30 arbitrary = (fromIntegral . fst . randomR (0,255::Int)) `fmap` rand
31 coarbitrary = undefined
35 "nil is null" ~: assertBool "" (U.null U.nil),
36 "namespaceDNS is not null" ~: assertBool "" (not $ U.null U.namespaceDNS)
40 "nil string" ~: U.toString U.nil @?= "00000000-0000-0000-0000-000000000000",
41 "nil bytes" ~: U.toByteString U.nil @?= B.pack (replicate 16 0)
45 "conv bytes to string" ~:
46 maybe "" (U.toString) (U.fromByteString b16) @?= s16,
47 "conv string to bytes" ~:
48 maybe B.empty (U.toByteString) (U.fromString s16) @?= b16
50 where b16 = B.pack [1..16]
51 s16 = "01020304-0506-0708-090a-0b0c0d0e0f10"
53test_v1 v1s = TestList [
54 "V1 unique" ~: nub (v1s \\ nub v1s) @?= [],
55 "V1 not null" ~: TestList $ map (testUUID (not . U.null)) v1s,
56 "V1 valid" ~: TestList $ map (testUUID (isValidVersion 1)) v1s
58 where testUUID :: (U.UUID -> Bool) -> Maybe U.UUID -> Test
59 testUUID p u = maybe False p u ~? show u
63 U.generateNamed U.namespaceDNS name @?= uV5
65 where name = map (fromIntegral . ord) "www.widgets.com" :: [Word8]
66 -- uV3 = fromJust $ U.fromString "3d813cbb-47fb-32ba-91df-831e1593ac29"
67 uV5 = fromJust $ U.fromString "21f7f8de-8051-5b89-8680-0195ef798b6a"
69prop_stringRoundTrip = label "String round trip" stringRoundTrip
70 where stringRoundTrip :: U.UUID -> Bool
71 stringRoundTrip u = maybe False (== u) $ U.fromString (U.toString u)
73prop_byteStringRoundTrip = label "ByteString round trip" byteStringRoundTrip
74 where byteStringRoundTrip :: U.UUID -> Bool
75 byteStringRoundTrip u = maybe False (== u)
76 $ U.fromByteString (U.toByteString u)
78prop_stringLength = label "String length" stringLength
79 where stringLength :: U.UUID -> Bool
80 stringLength u = length (U.toString u) == 36
82prop_byteStringLength = label "ByteString length" byteStringLength
83 where byteStringLength :: U.UUID -> Bool
84 byteStringLength u = B.length (U.toByteString u) == 16
86prop_randomsDiffer :: Property
87prop_randomsDiffer = label "Randoms differ" randomsDiffer
88 where randomsDiffer :: (U.UUID, U.UUID) -> Bool
89 randomsDiffer (u1, u2) = u1 /= u2
91prop_randomNotNull :: Property
92prop_randomNotNull = label "Random not null" randomNotNull
93 where randomNotNull :: U.UUID -> Bool
94 randomNotNull = not. U.null
96prop_randomsValid :: Property
97prop_randomsValid = label "Random valid" randomsValid
98 where randomsValid :: U.UUID -> Bool
99 randomsValid = isValidVersion 4
101prop_v5NotNull :: Property
102prop_v5NotNull = label "V5 not null" v5NotNull
103 where v5NotNull :: [Word8] -> Bool
104 v5NotNull = not . U.null . U.generateNamed U.namespaceDNS
106prop_v5Valid :: Property
107prop_v5Valid = label "V5 valid" v5Valid
108 where v5Valid :: [Word8] -> Bool
109 v5Valid = isValidVersion 5 . U.generateNamed U.namespaceDNS
114 v1s <- replicateM 100 U.nextUUID
115 runTestText (putTextToHandle stderr False) (TestList [
123 prop_stringRoundTrip,
124 prop_byteStringRoundTrip,
126 prop_byteStringLength,
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list