diff --git a/cassava-conduit.cabal b/cassava-conduit.cabal
--- a/cassava-conduit.cabal
+++ b/cassava-conduit.cabal
@@ -1,5 +1,5 @@
 name:               cassava-conduit
-version:            0.3.5
+version:            0.3.5.1
 license:            BSD3
 license-file:       etc/LICENCE.md
 author:             Dom De Re
@@ -55,6 +55,9 @@
     type:               exitcode-stdio-1.0
     main-is:            Main.hs
     hs-source-dirs:     quickcheck
+    other-modules:      Test.Arbitrary
+                        Test.Data.Csv.Conduit
+
     build-depends:      base                >= 4 && < 5
                       , bytestring          == 0.10.*
                       , cassava             == 0.4.*
diff --git a/quickcheck/Test/Arbitrary.hs b/quickcheck/Test/Arbitrary.hs
new file mode 100644
--- /dev/null
+++ b/quickcheck/Test/Arbitrary.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE OverloadedStrings #-}
+-------------------------------------------------------------------
+-- |
+-- Module       : Test.Arbitrary
+-- Copyright    : (C) 2016
+-- License      : BSD-style (see the file etc/LICENSE.md)
+-- Maintainer   : Dom De Re
+--
+-------------------------------------------------------------------
+module Test.Arbitrary (
+  -- * Generators
+    intCsvNoTrailingNewline
+  , intCsvTrailingNewline
+  , diceIt
+  ) where
+
+import Control.Monad (replicateM)
+
+import qualified Data.ByteString as BS
+import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
+
+import Test.QuickCheck (Arbitrary(..))
+import Test.QuickCheck.Gen (Gen, choose)
+
+import Prelude
+
+intColumns :: Int -> Gen [Int]
+intColumns s = replicateM s arbitrary
+
+intCsvNoTrailingNewlineText :: Gen (Int, T.Text)
+intCsvNoTrailingNewlineText = do
+  colSize <- choose (1, 30)
+  numRows <- choose (0, 150)
+  rows <- replicateM numRows (intColumns colSize)
+  let t = T.intercalate "\n" . fmap (T.intercalate "," . fmap (T.pack . show)) $ rows
+  pure (numRows, t)
+
+intCsvNoTrailingNewline :: Gen (Int, BS.ByteString)
+intCsvNoTrailingNewline = fmap T.encodeUtf8 <$> intCsvNoTrailingNewlineText
+
+intCsvTrailingNewline :: Gen (Int, BS.ByteString)
+intCsvTrailingNewline =
+  fmap (T.encodeUtf8 . flip T.snoc '\n') <$> intCsvNoTrailingNewlineText
+
+diceIt :: Gen (a, BS.ByteString) -> Gen (a, [BS.ByteString])
+diceIt g =
+  let
+    diceIt' :: BS.ByteString -> Gen [BS.ByteString]
+    diceIt' "" = pure []
+    diceIt' bs = do
+      chunkSize <- choose (3, 50)
+      let (chunk, remainder) = (BS.take chunkSize bs, BS.drop chunkSize bs)
+      (chunk :) <$> diceIt' remainder
+  in do
+    (rows, bs) <- g
+    ((,) rows) <$> diceIt' bs
+
+
diff --git a/quickcheck/Test/Data/Csv/Conduit.hs b/quickcheck/Test/Data/Csv/Conduit.hs
new file mode 100644
--- /dev/null
+++ b/quickcheck/Test/Data/Csv/Conduit.hs
@@ -0,0 +1,63 @@
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE TemplateHaskell #-}
+-------------------------------------------------------------------
+-- |
+-- Module       : Test.Data.Csv.Conduit
+-- Copyright    : (C) 2016
+-- License      : BSD-style (see the file etc/LICENSE.md)
+-- Maintainer   : Dom De Re
+--
+-------------------------------------------------------------------
+module Test.Data.Csv.Conduit where
+
+import Data.Csv.Conduit
+
+import qualified Data.ByteString as BS
+import Data.Csv (HasHeader(..), defaultDecodeOptions)
+import Data.Conduit (($$), (=$=))
+import Data.Conduit.List (sourceList, consume)
+import Data.Functor ((<$>))
+import Data.List (length)
+
+import Control.Applicative (pure)
+import Control.Monad (return)
+
+import Test.Arbitrary (
+    intCsvNoTrailingNewline
+  , intCsvTrailingNewline
+  , diceIt
+  )
+
+import Test.QuickCheck (Property, (===), forAll, quickCheckAll)
+import Test.QuickCheck.Gen (Gen)
+
+import Prelude (
+    IO
+  , Bool(..)
+  , Either
+  , Int
+  , ($)
+  )
+
+parsesAllRows :: Gen (Int, BS.ByteString) -> Property
+parsesAllRows g =
+  forAll (diceIt g) $ \(expectedRows, chunks) ->
+    let
+      result :: Either CsvParseError [[Int]]
+      result =
+            sourceList chunks
+        $$  fromCsv defaultDecodeOptions NoHeader
+        =$= consume
+    in (length <$> result) === pure expectedRows
+
+prop_parsesAllRowsWithNewline :: Property
+prop_parsesAllRowsWithNewline =
+  parsesAllRows intCsvTrailingNewline
+
+prop_parsesAllRowsWithNoNewline :: Property
+prop_parsesAllRowsWithNoNewline =
+  parsesAllRows intCsvNoTrailingNewline
+
+return []
+tests :: IO Bool
+tests = $quickCheckAll
