diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2014, Alp Mestanogullari
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Alp Mestanogullari nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/hspec-attoparsec.cabal b/hspec-attoparsec.cabal
new file mode 100644
--- /dev/null
+++ b/hspec-attoparsec.cabal
@@ -0,0 +1,51 @@
+name:                hspec-attoparsec
+version:             0.1.0.0
+synopsis:            Utility functions for testing your attoparsec parsers with hspec
+description:         This package provides some helper functions for testing attoparsec parsers with hspec.
+                     .
+                     See the documentation in @Test.Hspec.Attoparsec@ for examples, or this package's own test suite.
+homepage:            http://github.com/alpmestan/hspec-attoparsec
+Bug-reports:         https://github.com/alpmestan/hspec-attoparsec/issues
+license:             BSD3
+license-file:        LICENSE
+author:              Alp Mestanogullari
+maintainer:          alpmestan@gmail.com
+copyright:           2014 Alp Mestanogullari
+category:            Testing, Parsing
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Test.Hspec.Attoparsec,
+                       Test.Hspec.Attoparsec.Source
+  build-depends:       base >=4 && <5,
+                       attoparsec >= 0.10,
+                       hspec-expectations >= 0.5,
+                       bytestring >= 0.8,
+                       text >= 1.0
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+
+test-suite spec
+  type:
+      exitcode-stdio-1.0
+  ghc-options:
+      -Wall
+  hs-source-dirs:
+      src, tests
+  main-is:
+      Spec.hs
+  build-depends:
+      base    == 4.*
+    , text >= 1.0
+    , bytestring >= 0.8
+    , hspec
+    , hspec-expectations >= 0.5
+    , attoparsec >= 0.10
+  default-language:
+      Haskell2010
+
+source-repository head
+  type: git
+  location: http://github.com/alpmestan/hspec-attoparsec.git
diff --git a/src/Test/Hspec/Attoparsec.hs b/src/Test/Hspec/Attoparsec.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/Attoparsec.hs
@@ -0,0 +1,125 @@
+{-# LANGUAGE OverloadedStrings #-}
+-- |
+-- Module       : Test.Hspec.Attoparsec
+-- Copyright    : (c) 2014 Alp Mestanogullari
+-- License      : BSD3
+-- Maintainer   : alpmestan@gmail.com
+-- Stability    : experimental
+-- 
+-- Utility functions for testing @attoparsec@ parsers, each one providing
+-- an example of how to use it.
+module Test.Hspec.Attoparsec
+  ( -- * Equality-based combinator
+    shouldParse
+
+  , -- * Predicate-based combinator
+    parseSatisfies
+
+  , -- * Inspecting the result
+    shouldSucceedOn
+  , shouldFailOn
+
+  , -- * Inspecting unconsumed input
+    leavesUnconsumed
+
+  , -- * The 'Source' class, connecting parsers and inputs
+    Source(..)
+
+  , -- * The 'Leftover' class, letting us inspect unconsumed input
+    Leftover(..)
+  ) where
+
+import Control.Monad (when)
+import Data.Either (isLeft, isRight)
+import Test.Hspec.Attoparsec.Source
+import Test.Hspec.Expectations
+
+-- | Create an expectation by saying what the result should be.
+--   Intended to be used with '~>' as follows:
+--
+-- >   "<!-- foo -->" ~> htmlCommentParser
+-- >     `shouldParse` TagComment " foo "
+shouldParse :: (Eq a, Show a) => Either String a -> a -> Expectation
+res `shouldParse` expectedVal =
+  either (expectationFailure . errmsg)
+         checkEquality
+         res
+
+  where errmsg err =   "  expected: " ++ show expectedVal
+                  ++ "\n  but parsing failed with error: " ++ err
+
+        checkEquality parsedVal =
+          when (parsedVal /= expectedVal) $
+            expectationFailure $   "  expected: " ++ show expectedVal
+                              ++ "\n  but got: " ++ show parsedVal
+
+-- | Create an expectation by saying that the parser should successfully
+--   parse a value and that this value should satisfy some predicate.
+--   
+--   This can fail if the parsing doesn't succeed or if it succeeds but
+--   the value doesn't match the predicate.
+--
+-- > ">>>" ~> many (char '>')
+-- >   `parseSatisfies` ((==3) . length)
+parseSatisfies :: Show a => Either String a -> (a -> Bool) -> Expectation
+parseSatisfies res predicate =
+  either (expectationFailure . errmsg)
+         checkPred
+         res
+
+  where errmsg err =   "  expected a parsed value to check against the predicate"
+                  ++ "\n  but parsing failed with error: " ++ err
+
+        checkPred value =
+          when (not $ predicate value) $
+            expectationFailure $   
+                 "  the following value did not match the predicate: \n"
+              ++ "  " ++ show value
+
+-- | Check that a parser fails on some given input
+--
+-- > char 'x' `shouldFailOn` "a"
+shouldFailOn :: (Source p s s' r, Show a)
+             => p s' a
+             -> s
+             -> Expectation
+parser `shouldFailOn` string =
+  (string ~> parser) `shouldSatisfy` isLeft
+
+-- | Check that a parser succeeds on some given input
+--
+-- > char 'x' `shouldSucceedOn` "x"
+shouldSucceedOn :: (Source p s s' r, Show a)
+                => p s' a
+                -> s
+                -> Expectation
+parser `shouldSucceedOn` string =
+  (string ~> parser) `shouldSatisfy` isRight
+
+-- | Checking that the given parser succeeds
+--   and yields the given part of the input unconsumed.
+--   Intended to be used in conjunction with '~?>'
+--
+-- > ("xa" :: Text) ~?> char 'x'
+-- >   `leavesUnconsumed` "a"
+leavesUnconsumed :: (Source p s s' r, Leftover r s)
+                 => r a
+                 -> s
+                 -> Expectation
+leavesUnconsumed res str
+  | unconsumed == Nothing && str /= "" =
+      expectationFailure $ 
+           "  expected the parser to leave the following unconsumed: " ++ show str
+      ++ "\n  but got no leftover"
+  | otherwise = 
+      case unconsumed of
+        Just str' -> 
+          when (str /= str') $
+            expectationFailure $ 
+                   "  expected the parser to leave the following unconsumed: " ++ show str
+              ++ "\n  but got: " ++ show str'
+        Nothing -> expectationFailure $
+                          "  expected the parser to leave the following unconsumed: " ++ show str
+                     ++ "\n  but got no unconsumed input"
+
+  where unconsumed = leftover res
diff --git a/src/Test/Hspec/Attoparsec/Source.hs b/src/Test/Hspec/Attoparsec/Source.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/Attoparsec/Source.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE MultiParamTypeClasses,
+			 TypeSynonymInstances,
+			 FlexibleInstances,
+			 FunctionalDependencies #-}
+-- |
+-- Module       : Test.Hspec.Attoparsec.Source
+-- Copyright    : (c) 2014 Alp Mestanogullari
+-- License      : BSD3
+-- Maintainer   : alpmestan@gmail.com
+-- Stability    : experimental
+-- 
+-- A 'Source' class that ties parser types and input types to
+-- give you a uniform interface for testing your parsers,
+-- without caring about the input type.
+module Test.Hspec.Attoparsec.Source where 
+
+import qualified Data.Attoparsec.ByteString as AB
+import qualified Data.ByteString as B
+
+import qualified Data.Attoparsec.ByteString.Lazy as ALB
+import qualified Data.ByteString.Lazy as LB
+
+import qualified Data.Attoparsec.Text as AT
+import qualified Data.Text as T
+
+import qualified Data.Attoparsec.Text.Lazy as ALT
+import qualified Data.Text.Lazy as LT
+
+import qualified Data.Attoparsec.Types as Atto
+
+import Data.String (IsString)
+
+-- | A class where each instance will just teach
+--   how to get an Either or the specific result 
+--   type associated to the parser for the given
+--   input type.
+class (Eq string, Show string, IsString string)
+   => Source parser string string' result | string -> parser, string -> result, string -> string' where
+	-- | Feed some input to a parser and extract the result
+	--   as either a failure 'String' or an actually parsed value.
+	--   Can be read as /fed to/.
+	-- 
+	-- > -- "<a ...>" fed to an HTML parser 
+	-- > "<a href=\"/foo\">Go to foo</a>" ~> htmlParser :: Either String a
+	(~>) :: string -> parser string' a -> Either String a
+
+	-- | Feed some input to a parser and extract it as the
+	--   appropriate result type from that module.
+	-- 
+	--   This is not currently useful in the library per se,
+	--   but is used in test-suites directly where we generally only deal
+	--   with one concrete set of parser, input and result types.
+	--   This lets us inspect the result in any way we want, e.g
+	--   in conjunction with @shouldSatisfy@ or a custom hspec combinator.
+	(~?>) :: string -> parser string' a -> result a
+
+instance Source Atto.Parser B.ByteString B.ByteString AB.Result where
+	t ~> p = AB.parseOnly p t
+
+	t ~?> p = AB.parse p t
+
+instance Source Atto.Parser LB.ByteString B.ByteString ALB.Result where
+	t ~> p = ALB.eitherResult $ t ~?> p
+
+	t ~?> p = ALB.parse p t
+
+instance Source Atto.Parser T.Text T.Text AT.Result where
+	t ~> p = AT.parseOnly p t
+
+	t ~?> p = AT.parse p t
+
+instance Source Atto.Parser LT.Text T.Text ALT.Result where
+	t ~> p = ALT.eitherResult $ t ~?> p
+
+	t ~?> p = ALT.parse p t
+
+-- | Class for generically inspecting unconsumed input
+class Leftover r s | r -> s where
+	-- | Get the unconsumed input from the result of a parser
+	--   
+	--   Returns 'Nothing' if the unconsumed input is ""
+	leftover :: r a -> Maybe s
+
+instance Leftover AB.Result B.ByteString where
+	leftover (AB.Done t _) = Just t
+	leftover _             = Nothing
+
+instance Leftover ALB.Result LB.ByteString where
+	leftover (ALB.Done t _) = Just t
+	leftover _              = Nothing
+
+instance Leftover AT.Result T.Text where
+	leftover (AT.Done t _) = Just t
+	leftover _            = Nothing
+
+instance Leftover ALT.Result LT.Text where
+	leftover (ALT.Done t _) = Just t
+	leftover _              = Nothing
diff --git a/tests/Spec.hs b/tests/Spec.hs
new file mode 100644
--- /dev/null
+++ b/tests/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
