Skip to content

Commit 7c12a2d

Browse files
committed
Migrate tests from HUnit to QuickCheck
1 parent dd822a3 commit 7c12a2d

File tree

2 files changed

+92
-109
lines changed

2 files changed

+92
-109
lines changed

test/Test.hs

Lines changed: 91 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ import qualified Codec.Compression.Zlib.Raw as Raw
1010
import Test.Codec.Compression.Zlib.Internal ()
1111
import Test.Codec.Compression.Zlib.Stream ()
1212

13-
import Test.QuickCheck
1413
import Test.Tasty
1514
import Test.Tasty.QuickCheck
16-
import Test.Tasty.HUnit
1715
import Utils ()
1816

1917
import Control.Monad
@@ -45,17 +43,17 @@ main = defaultMain $
4543
testProperty "compress works with BSes with non-zero offset" prop_compress_nonzero_bs_offset
4644
],
4745
testGroup "unit tests" [
48-
testCase "simple gzip case" test_simple_gzip,
49-
testCase "detect bad crc" test_bad_crc,
50-
testCase "detect non-gzip" test_non_gzip,
51-
testCase "detect custom dictionary" test_custom_dict,
52-
testCase "dectect inflate with wrong dict" test_wrong_dictionary,
53-
testCase "dectect inflate with right dict" test_right_dictionary,
54-
testCase "handle trailing data" test_trailing_data,
55-
testCase "multiple gzip members" test_multiple_members,
56-
testCase "check small input chunks" test_small_chunks,
57-
testCase "check empty input" test_empty,
58-
testCase "check exception raised" test_exception
46+
testProperty "simple gzip case" test_simple_gzip,
47+
testProperty "detect bad crc" test_bad_crc,
48+
testProperty "detect non-gzip" test_non_gzip,
49+
testProperty "detect custom dictionary" test_custom_dict,
50+
testProperty "dectect inflate with wrong dict" test_wrong_dictionary,
51+
testProperty "dectect inflate with right dict" test_right_dictionary,
52+
testProperty "handle trailing data" test_trailing_data,
53+
testProperty "multiple gzip members" test_multiple_members,
54+
testProperty "check small input chunks" test_small_chunks,
55+
testProperty "check empty input" test_empty,
56+
testProperty "check exception raised" test_exception
5957
]
6058
]
6159

@@ -158,66 +156,55 @@ prop_compress_nonzero_bs_offset original to_drop =
158156
in dropped == to_drop && decompressed == input'
159157

160158

161-
test_simple_gzip :: Assertion
162-
test_simple_gzip =
159+
test_simple_gzip :: Property
160+
test_simple_gzip = ioProperty $
163161
withSampleData "hello.gz" $ \hnd ->
164162
let decomp = decompressIO gzipFormat defaultDecompressParams
165163
in assertDecompressOk hnd decomp
166164

167-
test_bad_crc :: Assertion
168-
test_bad_crc =
165+
test_bad_crc :: Property
166+
test_bad_crc = ioProperty $
169167
withSampleData "bad-crc.gz" $ \hnd -> do
170168
let decomp = decompressIO gzipFormat defaultDecompressParams
171-
err <- assertDecompressError hnd decomp
172-
msg <- assertDataFormatError err
173-
msg @?= "incorrect data check"
169+
assertDecompressError hnd (assertDataFormatError "incorrect data check") decomp
174170

175-
test_non_gzip :: Assertion
176-
test_non_gzip = do
177-
withSampleData "not-gzip" $ \hnd -> do
171+
test_non_gzip :: Property
172+
test_non_gzip = conjoin
173+
[ ioProperty $ withSampleData "not-gzip" $ \hnd -> do
178174
let decomp = decompressIO gzipFormat defaultDecompressParams
179-
err <- assertDecompressError hnd decomp
180-
msg <- assertDataFormatError err
181-
msg @?= "incorrect header check"
175+
assertDecompressError hnd (assertDataFormatError "incorrect header check") decomp
182176

183-
withSampleData "not-gzip" $ \hnd -> do
177+
, ioProperty $ withSampleData "not-gzip" $ \hnd -> do
184178
let decomp = decompressIO zlibFormat defaultDecompressParams
185-
err <- assertDecompressError hnd decomp
186-
msg <- assertDataFormatError err
187-
msg @?= "incorrect header check"
179+
assertDecompressError hnd (assertDataFormatError "incorrect header check") decomp
188180

189-
withSampleData "not-gzip" $ \hnd -> do
181+
, ioProperty $ withSampleData "not-gzip" $ \hnd -> do
190182
let decomp = decompressIO rawFormat defaultDecompressParams
191-
err <- assertDecompressError hnd decomp
192-
msg <- assertDataFormatError err
193-
msg @?= "invalid code lengths set"
183+
assertDecompressError hnd (assertDataFormatError "invalid code lengths set") decomp
194184

195-
withSampleData "not-gzip" $ \hnd -> do
185+
, ioProperty $ withSampleData "not-gzip" $ \hnd -> do
196186
let decomp = decompressIO gzipOrZlibFormat defaultDecompressParams
197-
err <- assertDecompressError hnd decomp
198-
msg <- assertDataFormatError err
199-
msg @?= "incorrect header check"
187+
assertDecompressError hnd (assertDataFormatError "incorrect header check") decomp
188+
]
200189

201-
test_custom_dict :: Assertion
202-
test_custom_dict =
190+
test_custom_dict :: Property
191+
test_custom_dict = ioProperty $
203192
withSampleData "custom-dict.zlib" $ \hnd -> do
204193
let decomp = decompressIO zlibFormat defaultDecompressParams
205-
err <- assertDecompressError hnd decomp
206-
err @?= DictionaryRequired
194+
assertDecompressError hnd (=== DictionaryRequired) decomp
207195

208-
test_wrong_dictionary :: Assertion
209-
test_wrong_dictionary = do
196+
test_wrong_dictionary :: Property
197+
test_wrong_dictionary = ioProperty $
210198
withSampleData "custom-dict.zlib" $ \hnd -> do
211199
let decomp = decompressIO zlibFormat defaultDecompressParams {
212200
decompressDictionary = -- wrong dict!
213201
Just (BS.pack [65,66,67])
214202
}
215203

216-
err <- assertDecompressError hnd decomp
217-
err @?= DictionaryMismatch
204+
assertDecompressError hnd (=== DictionaryMismatch) decomp
218205

219-
test_right_dictionary :: Assertion
220-
test_right_dictionary = do
206+
test_right_dictionary :: Property
207+
test_right_dictionary = ioProperty $
221208
withSampleData "custom-dict.zlib" $ \hnd -> do
222209
dict <- readSampleData "custom-dict.zlib-dict"
223210
let decomp = decompressIO zlibFormat defaultDecompressParams {
@@ -226,46 +213,48 @@ test_right_dictionary = do
226213
}
227214
assertDecompressOk hnd decomp
228215

229-
test_trailing_data :: Assertion
230-
test_trailing_data =
216+
test_trailing_data :: Property
217+
test_trailing_data = ioProperty $
231218
withSampleData "two-files.gz" $ \hnd -> do
232219
let decomp = decompressIO gzipFormat defaultDecompressParams {
233220
decompressAllMembers = False
234221
}
235-
chunks <- assertDecompressOkChunks hnd decomp
236-
case chunks of
237-
[chunk] -> chunk @?= BS.Char8.pack "Test 1"
238-
_ -> assertFailure "expected single chunk"
222+
checkChunks chunks = case chunks of
223+
[chunk] -> chunk === BS.Char8.pack "Test 1"
224+
_ -> counterexample "expected single chunk" False
225+
assertDecompressOkChunks hnd checkChunks decomp
226+
239227

240-
test_multiple_members :: Assertion
241-
test_multiple_members =
228+
test_multiple_members :: Property
229+
test_multiple_members = ioProperty $
242230
withSampleData "two-files.gz" $ \hnd -> do
243231
let decomp = decompressIO gzipFormat defaultDecompressParams {
244232
decompressAllMembers = True
245233
}
246-
chunks <- assertDecompressOkChunks hnd decomp
247-
case chunks of
248-
[chunk1,
249-
chunk2] -> do chunk1 @?= BS.Char8.pack "Test 1"
250-
chunk2 @?= BS.Char8.pack "Test 2"
251-
_ -> assertFailure "expected two chunks"
252-
253-
test_small_chunks :: Assertion
254-
test_small_chunks = do
234+
checkChunks chunks = case chunks of
235+
[chunk1, chunk2] ->
236+
chunk1 === BS.Char8.pack "Test 1" .&&. chunk2 === BS.Char8.pack "Test 2"
237+
_ -> counterexample "expected two chunks" False
238+
assertDecompressOkChunks hnd checkChunks decomp
239+
240+
test_small_chunks :: Property
241+
test_small_chunks = ioProperty $ do
255242
uncompressedFile <- readSampleData "not-gzip"
256-
GZip.compress (smallChunks uncompressedFile) @?= GZip.compress uncompressedFile
257-
Zlib.compress (smallChunks uncompressedFile) @?= Zlib.compress uncompressedFile
258-
Raw.compress (smallChunks uncompressedFile) @?= Raw.compress uncompressedFile
243+
compressedFile <- readSampleData "hello.gz"
244+
return $ conjoin
245+
[ GZip.compress (smallChunks uncompressedFile) === GZip.compress uncompressedFile
246+
, Zlib.compress (smallChunks uncompressedFile) === Zlib.compress uncompressedFile
247+
, Raw.compress (smallChunks uncompressedFile) === Raw.compress uncompressedFile
259248

260-
GZip.decompress (smallChunks (GZip.compress uncompressedFile)) @?= uncompressedFile
261-
Zlib.decompress (smallChunks (Zlib.compress uncompressedFile)) @?= uncompressedFile
262-
Raw.decompress (smallChunks (Raw.compress uncompressedFile)) @?= uncompressedFile
249+
, GZip.decompress (smallChunks (GZip.compress uncompressedFile)) === uncompressedFile
250+
, Zlib.decompress (smallChunks (Zlib.compress uncompressedFile)) === uncompressedFile
251+
, Raw.decompress (smallChunks (Raw.compress uncompressedFile)) === uncompressedFile
263252

264-
compressedFile <- readSampleData "hello.gz"
265-
(GZip.decompress . smallChunks) compressedFile @?= GZip.decompress compressedFile
253+
, (GZip.decompress . smallChunks) compressedFile === GZip.decompress compressedFile
254+
]
266255

267-
test_empty :: Assertion
268-
test_empty = do
256+
test_empty :: Property
257+
test_empty = ioProperty $ do
269258
-- Regression test to make sure we only ask for input once in the case of
270259
-- initially empty input. We previously asked for input twice before
271260
-- returning the error.
@@ -274,21 +263,18 @@ test_empty = do
274263
DecompressInputRequired next -> do
275264
decomp' <- next BS.empty
276265
case decomp' of
277-
DecompressStreamError TruncatedInput -> return ()
278-
_ -> assertFailure "expected truncated error"
279-
280-
_ -> assertFailure "expected input"
266+
DecompressStreamError TruncatedInput -> return $ property True
267+
_ -> return $ counterexample "expected truncated error" False
281268

282-
test_exception :: Assertion
283-
test_exception =
284-
(do
285-
compressedFile <- readSampleData "bad-crc.gz"
286-
_ <- evaluate (BL.length (GZip.decompress compressedFile))
287-
assertFailure "expected exception")
269+
_ -> return $ counterexample "expected input" False
288270

289-
`catch` \err -> do
290-
msg <- assertDataFormatError err
291-
msg @?= "incorrect data check"
271+
test_exception :: Property
272+
test_exception = ioProperty $ do
273+
compressedFile <- readSampleData "bad-crc.gz"
274+
len <- try (evaluate (BL.length (GZip.decompress compressedFile)))
275+
return $ case len of
276+
Left err -> assertDataFormatError "incorrect data check" err
277+
Right{} -> counterexample "expected exception" False
292278

293279
toStrict :: BL.ByteString -> BS.ByteString
294280
#if MIN_VERSION_bytestring(0,10,0)
@@ -325,35 +311,33 @@ readSampleData file = BL.readFile ("test/data/" ++ file)
325311
withSampleData :: FilePath -> (Handle -> IO a) -> IO a
326312
withSampleData file = withFile ("test/data/" ++ file) ReadMode
327313

328-
expected :: String -> String -> IO a
329-
expected e g = assertFailure ("expected: " ++ e ++ "\nbut got: " ++ g)
330-
>> fail ""
314+
expected :: String -> String -> Property
315+
expected e g = counterexample ("expected: " ++ e ++ "\nbut got: " ++ g) False
331316

332-
assertDecompressOk :: Handle -> DecompressStream IO -> Assertion
317+
assertDecompressOk :: Handle -> DecompressStream IO -> IO Property
333318
assertDecompressOk hnd =
334319
foldDecompressStream
335320
(BS.hGet hnd 4000 >>=)
336321
(\_ r -> r)
337-
(\_ -> return ())
338-
(\err -> expected "decompress ok" (show err))
322+
(\_ -> return $ property True)
323+
(\err -> return $ expected "decompress ok" (show err))
339324

340-
assertDecompressOkChunks :: Handle -> DecompressStream IO -> IO [BS.ByteString]
341-
assertDecompressOkChunks hnd =
325+
assertDecompressOkChunks :: Handle -> ([BS.ByteString] -> Property) -> DecompressStream IO -> IO Property
326+
assertDecompressOkChunks hnd callback = fmap (either id callback) .
342327
foldDecompressStream
343328
(BS.hGet hnd 4000 >>=)
344-
(\chunk -> liftM (chunk:))
345-
(\_ -> return [])
346-
(\err -> expected "decompress ok" (show err))
329+
(\chunk -> liftM (liftM (chunk:)))
330+
(\_ -> return $ Right [])
331+
(\err -> return $ Left $ expected "decompress ok" (show err))
347332

348-
assertDecompressError :: Handle -> DecompressStream IO -> IO DecompressError
349-
assertDecompressError hnd =
333+
assertDecompressError :: Handle -> (DecompressError -> Property) -> DecompressStream IO -> IO Property
334+
assertDecompressError hnd callback =
350335
foldDecompressStream
351336
(BS.hGet hnd 4000 >>=)
352337
(\_ r -> r)
353-
(\_ -> expected "StreamError" "StreamEnd")
354-
return
338+
(\_ -> return $ expected "StreamError" "StreamEnd")
339+
(return . callback)
355340

356-
assertDataFormatError :: DecompressError -> IO String
357-
assertDataFormatError (DataFormatError detail) = return detail
358-
assertDataFormatError _ = assertFailure "expected DataError"
359-
>> return ""
341+
assertDataFormatError :: String -> DecompressError -> Property
342+
assertDataFormatError expect (DataFormatError actual) = expect === actual
343+
assertDataFormatError _ _ = counterexample "expected DataError" False

zlib.cabal

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,5 @@ test-suite tests
132132
build-depends: base, bytestring, zlib,
133133
QuickCheck == 2.*,
134134
tasty >= 0.8 && < 1.5,
135-
tasty-quickcheck >= 0.8 && < 0.11,
136-
tasty-hunit >= 0.8 && < 0.11
135+
tasty-quickcheck >= 0.8 && < 0.11
137136
ghc-options: -Wall

0 commit comments

Comments
 (0)