diff --git a/bench-src/Codec/Binary/Base16Bench.hs b/bench-src/Codec/Binary/Base16Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/Base16Bench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.Base16Bench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Base16
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc base 16 1M" $ nf encode data1M
+        , bench "dec base 16 1M" $ nf decode enc1M
+        , bench "enc base 16 10M" $ nf encode data10M
+        , bench "dec base 16 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/Base32Bench.hs b/bench-src/Codec/Binary/Base32Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/Base32Bench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.Base32Bench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Base32
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc base 32 1M" $ nf encode data1M
+        , bench "dec base 32 1M" $ nf decode enc1M
+        , bench "enc base 32 10M" $ nf encode data10M
+        , bench "dec base 32 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/Base32HexBench.hs b/bench-src/Codec/Binary/Base32HexBench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/Base32HexBench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.Base32HexBench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Base32Hex
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc base 32 hex 1M" $ nf encode data1M
+        , bench "dec base 32 hex 1M" $ nf decode enc1M
+        , bench "enc base 32 hex 10M" $ nf encode data10M
+        , bench "dec base 32 hex 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/Base64Bench.hs b/bench-src/Codec/Binary/Base64Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/Base64Bench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.Base64Bench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Base64
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc base 64 1M" $ nf encode data1M
+        , bench "dec base 64 1M" $ nf decode enc1M
+        , bench "enc base 64 10M" $ nf encode data10M
+        , bench "dec base 64 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/Base64UrlBench.hs b/bench-src/Codec/Binary/Base64UrlBench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/Base64UrlBench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.Base64UrlBench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Base64Url
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc base 64 url 1M" $ nf encode data1M
+        , bench "dec base 64 url 1M" $ nf decode enc1M
+        , bench "enc base 64 url 10M" $ nf encode data10M
+        , bench "dec base 64 url 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/Base85Bench.hs b/bench-src/Codec/Binary/Base85Bench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/Base85Bench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.Base85Bench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Base85
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc base 85 1M" $ nf encode data1M
+        , bench "dec base 85 1M" $ nf decode enc1M
+        , bench "enc base 85 10M" $ nf encode data10M
+        , bench "dec base 85 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/QuotedPrintableBench.hs b/bench-src/Codec/Binary/QuotedPrintableBench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/QuotedPrintableBench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.QuotedPrintableBench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.QuotedPrintable
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc quoted printable 1M" $ nf encode data1M
+        , bench "dec quoted printable 1M" $ nf decode enc1M
+        , bench "enc quoted printable 10M" $ nf encode data10M
+        , bench "dec quoted printable 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/UuBench.hs b/bench-src/Codec/Binary/UuBench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/UuBench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.UuBench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Uu
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc uu 1M" $ nf encode data1M
+        , bench "dec uu 1M" $ nf decode enc1M
+        , bench "enc uu 10M" $ nf encode data10M
+        , bench "dec uu 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/XxBench.hs b/bench-src/Codec/Binary/XxBench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/XxBench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.XxBench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Xx
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc xx 1M" $ nf encode data1M
+        , bench "dec xx 1M" $ nf decode enc1M
+        , bench "enc xx 10M" $ nf encode data10M
+        , bench "dec xx 10M" $ nf decode enc10M
+        ]
diff --git a/bench-src/Codec/Binary/YencBench.hs b/bench-src/Codec/Binary/YencBench.hs
new file mode 100644
--- /dev/null
+++ b/bench-src/Codec/Binary/YencBench.hs
@@ -0,0 +1,15 @@
+module Codec.Binary.YencBench where
+
+import Criterion.Main (bench, nf)
+
+import Codec.Binary.Yenc
+
+mkBenchs data1M data10M = let
+        enc1M = encode data1M
+        enc10M = encode data10M
+    in
+        [ bench "enc yenc 1M" $ nf encode data1M
+        , bench "dec yenc 1M" $ nf decode enc1M
+        , bench "enc yenc 10M" $ nf encode data10M
+        , bench "dec yenc 10M" $ nf decode enc10M
+        ]
diff --git a/sandi.cabal b/sandi.cabal
--- a/sandi.cabal
+++ b/sandi.cabal
@@ -1,5 +1,5 @@
 name: sandi
-version: 0.2.1
+version: 0.2.2
 license: BSD3
 license-file: LICENSE
 cabal-version: >= 1.8
@@ -54,7 +54,6 @@
 test-suite sandi-tests
     type: exitcode-stdio-1.0
     hs-source-dirs: src, test-src
-    main-is: Main.hs
     build-depends:
         sandi,
         base,
@@ -64,13 +63,36 @@
         test-framework-hunit,
         test-framework-th,
         test-framework
+    main-is: Main.hs
+    other-modules:
+        Codec.Binary.Base16Test
+        Codec.Binary.Base32HexTest
+        Codec.Binary.Base32Test
+        Codec.Binary.Base64Test
+        Codec.Binary.Base64UrlTest
+        Codec.Binary.Base85Test
+        Codec.Binary.QuotedPrintableTest
+        Codec.Binary.UuTest
+        Codec.Binary.XxTest
+        Codec.Binary.YencTest
 
 benchmark sandi-bench
     type: exitcode-stdio-1.0
     hs-source-dirs:   src, bench-src
-    main-is: Main.hs
     build-depends:
         sandi,
         base,
         bytestring,
         criterion
+    main-is: Main.hs
+    other-modules:
+        Codec.Binary.Base16Bench
+        Codec.Binary.Base32Bench
+        Codec.Binary.Base32HexBench
+        Codec.Binary.Base64Bench
+        Codec.Binary.Base64UrlBench
+        Codec.Binary.Base85Bench
+        Codec.Binary.QuotedPrintableBench
+        Codec.Binary.UuBench
+        Codec.Binary.XxBench
+        Codec.Binary.YencBench
diff --git a/test-src/Codec/Binary/Base16Test.hs b/test-src/Codec/Binary/Base16Test.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/Base16Test.hs
@@ -0,0 +1,48 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.Base16Test where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Base16 as B16
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_b16_enc_foobar :: IO ()
+case_b16_enc_foobar = do
+    BSC.empty               @=? B16.encode BSC.empty
+    BSC.pack "66"           @=? B16.encode (BSC.pack "f")
+    BSC.pack "666F"         @=? B16.encode (BSC.pack "fo")
+    BSC.pack "666F6F"       @=? B16.encode (BSC.pack "foo")
+    BSC.pack "666F6F62"     @=? B16.encode (BSC.pack "foob")
+    BSC.pack "666F6F6261"   @=? B16.encode (BSC.pack "fooba")
+    BSC.pack "666F6F626172" @=? B16.encode (BSC.pack "foobar")
+
+case_b16_dec_foobar :: IO ()
+case_b16_dec_foobar = do
+    Right BS.empty            @=? B16.decode BS.empty
+    Right (BSC.pack "f")      @=? B16.decode (BSC.pack "66")
+    Right (BSC.pack "fo")     @=? B16.decode (BSC.pack "666F")
+    Right (BSC.pack "foo")    @=? B16.decode (BSC.pack "666F6F")
+    Right (BSC.pack "foob")   @=? B16.decode (BSC.pack "666F6F62")
+    Right (BSC.pack "fooba")  @=? B16.decode (BSC.pack "666F6F6261")
+    Right (BSC.pack "foobar") @=? B16.decode (BSC.pack "666F6F626172")
+
+case_b16_dec_failure :: IO ()
+case_b16_dec_failure = do
+    -- odd number of input bytes
+    (Left (BSC.pack "fooba", BS.pack [55])) @=? (B16.decode $ BS.pack [54,54,54,70,54,70,54,50,54,49,55])
+
+prop_b16_encdec :: [Word8] -> Bool
+prop_b16_encdec ws = (BS.pack ws) == (fromRight $ B16.decode $ B16.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base32HexTest.hs b/test-src/Codec/Binary/Base32HexTest.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/Base32HexTest.hs
@@ -0,0 +1,52 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.Base32HexTest where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Base32Hex as B32H
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BSC.empty                   @=? B32H.encode BS.empty
+    BSC.pack "CO======"         @=? B32H.encode (BSC.pack "f")
+    BSC.pack "CPNG===="         @=? B32H.encode (BSC.pack "fo")
+    BSC.pack "CPNMU==="         @=? B32H.encode (BSC.pack "foo")
+    BSC.pack "CPNMUOG="         @=? B32H.encode (BSC.pack "foob")
+    BSC.pack "CPNMUOJ1"         @=? B32H.encode (BSC.pack "fooba")
+    BSC.pack "CPNMUOJ1E8======" @=? B32H.encode (BSC.pack "foobar")
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BS.empty            @=? B32H.decode BS.empty
+    Right (BSC.pack "f")      @=? B32H.decode (BSC.pack "CO======")
+    Right (BSC.pack "fo")     @=? B32H.decode (BSC.pack "CPNG====")
+    Right (BSC.pack "foo")    @=? B32H.decode (BSC.pack "CPNMU===")
+    Right (BSC.pack "foob")   @=? B32H.decode (BSC.pack "CPNMUOG=")
+    Right (BSC.pack "fooba")  @=? B32H.decode (BSC.pack "CPNMUOJ1")
+    Right (BSC.pack "foobar") @=? B32H.decode (BSC.pack "CPNMUOJ1E8======")
+
+case_dec_failures :: IO ()
+case_dec_failures = do
+    --  illegal char
+    Left (BS.empty, BSC.pack "C=NMUOJ1") @=? (B32H.b32h_decode_part $ BSC.pack "C=NMUOJ1")
+    -- full block
+    Nothing @=? (B32H.b32h_decode_final $ BSC.pack "CPNMUOJ1")
+    -- too short
+    Nothing @=? (B32H.b32h_decode_final $ BSC.pack "CPNMUO=")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ B32H.decode $ B32H.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base32Test.hs b/test-src/Codec/Binary/Base32Test.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/Base32Test.hs
@@ -0,0 +1,52 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.Base32Test where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Base32 as B32
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BSC.empty                   @=? B32.encode BSC.empty
+    BSC.pack "MY======"         @=? B32.encode (BSC.pack "f")
+    BSC.pack "MZXQ===="         @=? B32.encode (BSC.pack "fo")
+    BSC.pack "MZXW6==="         @=? B32.encode (BSC.pack "foo")
+    BSC.pack "MZXW6YQ="         @=? B32.encode (BSC.pack "foob")
+    BSC.pack "MZXW6YTB"         @=? B32.encode (BSC.pack "fooba")
+    BSC.pack "MZXW6YTBOI======" @=? B32.encode (BSC.pack "foobar")
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BS.empty            @=? B32.decode BS.empty
+    Right (BSC.pack "f")      @=? B32.decode (BSC.pack "MY======")
+    Right (BSC.pack "fo")     @=? B32.decode (BSC.pack "MZXQ====")
+    Right (BSC.pack "foo")    @=? B32.decode (BSC.pack "MZXW6===")
+    Right (BSC.pack "foob")   @=? B32.decode (BSC.pack "MZXW6YQ=")
+    Right (BSC.pack "fooba")  @=? B32.decode (BSC.pack "MZXW6YTB")
+    Right (BSC.pack "foobar") @=? B32.decode (BSC.pack "MZXW6YTBOI======")
+
+case_dec_failures :: IO ()
+case_dec_failures = do
+    -- illegal char
+    Left (BSC.empty, BSC.pack "M=XW6YTB") @=? (B32.b32_decode_part $ BSC.pack "M=XW6YTB")
+    -- full block
+    Nothing @=? (B32.b32_decode_final $ BSC.pack "MZXW6YTB")
+    -- too short
+    Nothing @=? (B32.b32_decode_final $ BSC.pack "MZXW6Y=")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ B32.decode $ B32.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base64Test.hs b/test-src/Codec/Binary/Base64Test.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/Base64Test.hs
@@ -0,0 +1,53 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.Base64Test where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Base64 as B64
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BSC.empty           @=? B64.encode BSC.empty
+    BSC.pack "Zg=="     @=? B64.encode (BSC.pack "f")
+    BSC.pack "Zm8="     @=? B64.encode (BSC.pack "fo")
+    BSC.pack "Zm9v"     @=? B64.encode (BSC.pack "foo")
+    BSC.pack "Zm9vYg==" @=? B64.encode (BSC.pack "foob")
+    BSC.pack "Zm9vYmE=" @=? B64.encode (BSC.pack "fooba")
+    BSC.pack "Zm9vYmFy" @=? B64.encode (BSC.pack "foobar")
+
+case_enc_specials :: IO ()
+case_enc_specials = do
+    -- /++/
+    BSC.pack "/++/" @=? B64.encode (BS.pack [255,239,191])
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BSC.empty           @=? B64.decode BSC.empty
+    Right (BSC.pack "f")      @=? B64.decode (BSC.pack "Zg==")
+    Right (BSC.pack "fo")     @=? B64.decode (BSC.pack "Zm8=")
+    Right (BSC.pack "foo")    @=? B64.decode (BSC.pack "Zm9v")
+    Right (BSC.pack "foob")   @=? B64.decode (BSC.pack "Zm9vYg==")
+    Right (BSC.pack "fooba")  @=? B64.decode (BSC.pack "Zm9vYmE=")
+    Right (BSC.pack "foobar") @=? B64.decode (BSC.pack "Zm9vYmFy")
+
+case_dec_specials :: IO ()
+case_dec_specials = do
+    -- /++/
+    Right (BS.pack [255,239,191]) @=? B64.decode (BSC.pack "/++/")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ B64.decode $ B64.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base64UrlTest.hs b/test-src/Codec/Binary/Base64UrlTest.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/Base64UrlTest.hs
@@ -0,0 +1,53 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.Base64UrlTest where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Base64Url as B64U
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BSC.empty           @=? B64U.encode BSC.empty
+    BSC.pack "Zg=="     @=? B64U.encode (BSC.pack "f")
+    BSC.pack "Zm8="     @=? B64U.encode (BSC.pack "fo")
+    BSC.pack "Zm9v"     @=? B64U.encode (BSC.pack "foo")
+    BSC.pack "Zm9vYg==" @=? B64U.encode (BSC.pack "foob")
+    BSC.pack "Zm9vYmE=" @=? B64U.encode (BSC.pack "fooba")
+    BSC.pack "Zm9vYmFy" @=? B64U.encode (BSC.pack "foobar")
+
+case_enc_specials :: IO ()
+case_enc_specials = do
+    -- _--_
+    BSC.pack "_--_" @=? (B64U.encode $ BS.pack [255,239,191])
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BSC.empty           @=? B64U.decode BSC.empty
+    Right (BSC.pack "f")      @=? B64U.decode (BSC.pack "Zg==")
+    Right (BSC.pack "fo")     @=? B64U.decode (BSC.pack "Zm8=")
+    Right (BSC.pack "foo")    @=? B64U.decode (BSC.pack "Zm9v")
+    Right (BSC.pack "foob")   @=? B64U.decode (BSC.pack "Zm9vYg==")
+    Right (BSC.pack "fooba")  @=? B64U.decode (BSC.pack "Zm9vYmE=")
+    Right (BSC.pack "foobar") @=? B64U.decode (BSC.pack "Zm9vYmFy")
+
+case_dec_specials :: IO ()
+case_dec_specials = do
+    -- _--_
+    Right (BS.pack [255,239,191]) @=? B64U.decode (BSC.pack "_--_")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ B64U.decode $ B64U.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/Base85Test.hs b/test-src/Codec/Binary/Base85Test.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/Base85Test.hs
@@ -0,0 +1,62 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.Base85Test where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Base85 as B85
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BS.empty @=? B85.encode BS.empty
+    BSC.pack "Ac"       @=? B85.encode (BSC.pack "f")
+    BSC.pack "Ao@"      @=? B85.encode (BSC.pack "fo")
+    BSC.pack "AoDS"     @=? B85.encode (BSC.pack "foo")
+    BSC.pack "AoDTs"    @=? B85.encode (BSC.pack "foob")
+    BSC.pack "AoDTs@/"  @=? B85.encode (BSC.pack "fooba")
+    BSC.pack "AoDTs@<)" @=? B85.encode (BSC.pack "foobar")
+
+case_enc_specials :: IO ()
+case_enc_specials = do
+    -- all zero
+    BSC.pack "z" @=? B85.encode (BS.pack [0,0,0,0])
+    -- all space
+    BSC.pack "y" @=? B85.encode (BS.pack [32,32,32,32])
+    -- double special
+    BSC.pack "yz" @=? B85.encode (BS.pack [32,32,32,32,0,0,0,0])
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    -- foobar
+    Right BS.empty            @=? B85.decode BS.empty
+    Right (BSC.pack "f")      @=? B85.decode (BSC.pack "Ac")
+    Right (BSC.pack "fo")     @=? B85.decode (BSC.pack "Ao@")
+    Right (BSC.pack "foo")    @=? B85.decode (BSC.pack "AoDS")
+    Right (BSC.pack "foob")   @=? B85.decode (BSC.pack "AoDTs")
+    Right (BSC.pack "fooba")  @=? B85.decode (BSC.pack "AoDTs@/")
+    Right (BSC.pack "foobar") @=? B85.decode (BSC.pack "AoDTs@<)")
+
+case_dec_specials :: IO ()
+case_dec_specials = do
+    -- all zero
+    Right (BS.pack [0,0,0,0]) @=? B85.decode (BSC.pack "z")
+    -- all space
+    Right (BS.pack [32,32,32,32]) @=? B85.decode (BSC.pack "y")
+    -- double special
+    Right (BS.pack [32,32,32,32,0,0,0,0]) @=? B85.decode (BSC.pack "yz")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ B85.decode $ B85.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/QuotedPrintableTest.hs b/test-src/Codec/Binary/QuotedPrintableTest.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/QuotedPrintableTest.hs
@@ -0,0 +1,33 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.QuotedPrintableTest where
+
+import Codec.TestUtils
+import qualified Codec.Binary.QuotedPrintable as QP
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BS.empty          @=? QP.encode BS.empty
+    BSC.pack "foobar" @=? QP.encode (BSC.pack "foobar")
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BS.empty            @=? QP.decode BS.empty
+    Right (BSC.pack "foobar") @=? QP.decode (BSC.pack "foobar")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ QP.decode $ QP.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/UuTest.hs b/test-src/Codec/Binary/UuTest.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/UuTest.hs
@@ -0,0 +1,43 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.UuTest where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Uu as Uu
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BS.empty            @=? Uu.encode BS.empty
+    BSC.pack "9@"       @=? Uu.encode (BSC.pack "f")
+    BSC.pack "9F\\"     @=? Uu.encode (BSC.pack "fo")
+    BSC.pack "9F]O"     @=? Uu.encode (BSC.pack "foo")
+    BSC.pack "9F]O8@"   @=? Uu.encode (BSC.pack "foob")
+    BSC.pack "9F]O8F$"  @=? Uu.encode (BSC.pack "fooba")
+    BSC.pack "9F]O8F%R" @=? Uu.encode (BSC.pack "foobar")
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BS.empty            @=? Uu.decode BS.empty
+    Right (BSC.pack "f")      @=? Uu.decode (BSC.pack "9@")
+    Right (BSC.pack "fo")     @=? Uu.decode (BSC.pack "9F\\")
+    Right (BSC.pack "foo")    @=? Uu.decode (BSC.pack "9F]O")
+    Right (BSC.pack "foob")   @=? Uu.decode (BSC.pack "9F]O8@")
+    Right (BSC.pack "fooba")  @=? Uu.decode (BSC.pack "9F]O8F$")
+    Right (BSC.pack "foobar") @=? Uu.decode (BSC.pack "9F]O8F%R")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ Uu.decode $ Uu.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/XxTest.hs b/test-src/Codec/Binary/XxTest.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/XxTest.hs
@@ -0,0 +1,43 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.XxTest where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Xx as Xx
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BS.empty            @=? Xx.encode BS.empty
+    BSC.pack "NU"       @=? Xx.encode (BSC.pack "f")
+    BSC.pack "Naw"      @=? Xx.encode (BSC.pack "fo")
+    BSC.pack "Naxj"     @=? Xx.encode (BSC.pack "foo")
+    BSC.pack "NaxjMU"   @=? Xx.encode (BSC.pack "foob")
+    BSC.pack "NaxjMa2"  @=? Xx.encode (BSC.pack "fooba")
+    BSC.pack "NaxjMa3m" @=? Xx.encode (BSC.pack "foobar")
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BS.empty            @=? Xx.decode BS.empty
+    Right (BSC.pack "f")      @=? Xx.decode (BSC.pack "NU")
+    Right (BSC.pack "fo")     @=? Xx.decode (BSC.pack "Naw")
+    Right (BSC.pack "foo")    @=? Xx.decode (BSC.pack "Naxj")
+    Right (BSC.pack "foob")   @=? Xx.decode (BSC.pack "NaxjMU")
+    Right (BSC.pack "fooba")  @=? Xx.decode (BSC.pack "NaxjMa2")
+    Right (BSC.pack "foobar") @=? Xx.decode (BSC.pack "NaxjMa3m")
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ Xx.decode $ Xx.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
diff --git a/test-src/Codec/Binary/YencTest.hs b/test-src/Codec/Binary/YencTest.hs
new file mode 100644
--- /dev/null
+++ b/test-src/Codec/Binary/YencTest.hs
@@ -0,0 +1,59 @@
+{-# OPTIONS_GHC -XTemplateHaskell #-}
+-- Copyright: (c) Magnus Therning, 2013
+-- License: BSD3, found in the LICENSE file
+
+module Codec.Binary.YencTest where
+
+import Codec.TestUtils
+import qualified Codec.Binary.Yenc as Y
+
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as BSC
+import Test.HUnit
+import Test.Framework (Test)
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Data.Word (Word8)
+
+case_enc_foobar :: IO ()
+case_enc_foobar = do
+    BS.empty                          @=? Y.encode BS.empty
+    BS.pack [144]                     @=? Y.encode (BSC.pack "f")
+    BS.pack [144,153]                 @=? Y.encode (BSC.pack "fo")
+    BS.pack [144,153,153]             @=? Y.encode (BSC.pack "foo")
+    BS.pack [144,153,153,140]         @=? Y.encode (BSC.pack "foob")
+    BS.pack [144,153,153,140,139]     @=? Y.encode (BSC.pack "fooba")
+    BS.pack [144,153,153,140,139,156] @=? Y.encode (BSC.pack "foobar")
+
+case_enc_specials :: IO ()
+case_enc_specials = do
+    -- expanded chars
+    BS.pack [61,64]  @=? Y.encode (BS.pack [214])
+    BS.pack [61,74]  @=? Y.encode (BS.pack [224])
+    BS.pack [61,77]  @=? Y.encode (BS.pack [227])
+    BS.pack [61,125] @=? Y.encode (BS.pack [19])
+
+case_dec_foobar :: IO ()
+case_dec_foobar = do
+    Right BS.empty            @=? Y.decode BS.empty
+    Right (BSC.pack "f")      @=? Y.decode (BS.pack [144])
+    Right (BSC.pack "fo")     @=? Y.decode (BS.pack [144,153])
+    Right (BSC.pack "foo")    @=? Y.decode (BS.pack [144,153,153])
+    Right (BSC.pack "foob")   @=? Y.decode (BS.pack [144,153,153,140])
+    Right (BSC.pack "fooba")  @=? Y.decode (BS.pack [144,153,153,140,139])
+    Right (BSC.pack "foobar") @=? Y.decode (BS.pack [144,153,153,140,139,156])
+
+case_dec_specials :: IO ()
+case_dec_specials = do
+    -- expanded chars
+    Right (BS.pack [214]) @=? Y.decode (BS.pack [61,64])
+    Right (BS.pack [224]) @=? Y.decode (BS.pack [61,74])
+    Right (BS.pack [227]) @=? Y.decode (BS.pack [61,77])
+    Right (BS.pack [19])  @=? Y.decode (BS.pack [61,125])
+
+prop_encdec :: [Word8] -> Bool
+prop_encdec ws = (BS.pack ws) == (fromRight $ Y.decode $ Y.encode $ BS.pack ws)
+
+tests :: Test.Framework.Test
+tests = $(testGroupGenerator)
