diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) vi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
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/assertions.cabal b/assertions.cabal
new file mode 100644
--- /dev/null
+++ b/assertions.cabal
@@ -0,0 +1,28 @@
+name:                assertions
+version:             0.1.0.3
+synopsis:            A simple testing framework.
+license:             MIT
+license-file:        LICENSE
+data-files:         
+  test/fixtures/Green.hs
+  test/fixtures/Mixed.hs
+  test/fixtures/Red.hs
+author:              vi
+maintainer:          me@vikramverma.com
+category:            Testing
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src 
+  exposed-modules:     Test.Assert
+  build-depends:       base >=4.6 && <4.7, containers, ansi-terminal
+  default-language:    Haskell2010
+
+test-suite assert-tests
+  type:                exitcode-stdio-1.0
+  main-is:             Assert.hs
+  hs-source-dirs:      test
+  build-depends:       base, assertions, interpolate, process
+  default-language:    Haskell2010
+  other-modules:       Paths_assertions
diff --git a/src/Test/Assert.hs b/src/Test/Assert.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Assert.hs
@@ -0,0 +1,34 @@
+module Test.Assert (runAssertions) where
+
+import System.Console.ANSI (setSGR, SGR(..), ConsoleLayer(..), ColorIntensity(..), Color(..))
+import System.Exit (exitSuccess, exitFailure)
+import Text.Printf (printf)
+import Data.Monoid (Monoid(..))
+
+data Assertion = Assertion [(Color, String)] Integer Integer
+
+instance Monoid Assertion where
+  (Assertion a0 b0 c0) `mappend` (Assertion a1 b1 c1) = Assertion (a0++a1) (b0+b1) (c0+c1)
+  mempty = Assertion [] 0 0
+
+toAssertion :: (String, Bool) -> Assertion
+toAssertion (s,b) = Assertion [(c,s)] p 1
+  where (c, p) = if b then (Green,1) else (Red,0)
+
+putOut :: (Color, String) -> IO ()
+putOut (c,s) = setSGR [SetColor Foreground Dull c]
+            >> putStrLn s
+            >> setSGR []
+
+showRatio :: Integer -> Integer -> String
+showRatio a b = printf "%.2f" . (100*) $ ratio
+  where ratio = (fromIntegral a) / (fromIntegral b) :: Float
+
+assert :: Assertion -> IO ()
+assert (Assertion out pass total) = do
+  mapM_ putOut out
+  putStrLn . concat $ [showRatio pass total, "% of tests passed."]
+  if pass == total then exitSuccess else exitFailure
+
+runAssertions :: [(String, Bool)] -> IO ()
+runAssertions = assert . mconcat . map toAssertion
diff --git a/test/Assert.hs b/test/Assert.hs
new file mode 100644
--- /dev/null
+++ b/test/Assert.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE QuasiQuotes #-}
+
+module Main (main) where
+
+import Control.Applicative ((<$>))
+import Data.String.Interpolate (i)
+import System.Cmd (system)
+import System.Exit (ExitCode(..))
+import Test.Assert (runAssertions)
+import Paths_assertions (getDataFileName)
+
+is0 :: ExitCode -> Bool
+is0 = (== ExitSuccess)
+
+is1 :: ExitCode -> Bool
+is1 = (== ExitFailure 1)
+
+quietly :: String -> IO ExitCode
+quietly = system . (++"&>/dev/null")
+
+main :: IO ()
+main = getDataFileName "test/fixtures" >>= \fixtures -> do
+  greenTest <- is0 <$> quietly [i|runhaskell #{fixtures}/Green.hs|]
+  redTest   <- is1 <$> quietly [i|runhaskell #{fixtures}/Red.hs|]
+  mixedTest <- is1 <$> quietly [i|runhaskell #{fixtures}/Mixed.hs|]
+  runAssertions $
+    [ ("When all tests in a suite pass, it should exit with 0.", greenTest)
+    , ("When some but not all of the tests in a suite pass, it should exit with 1.", mixedTest)
+    , ("When all of the tests in a suite fail, it should exit with 1.", redTest)
+    ]
diff --git a/test/fixtures/Green.hs b/test/fixtures/Green.hs
new file mode 100644
--- /dev/null
+++ b/test/fixtures/Green.hs
@@ -0,0 +1,10 @@
+import Test.Assert (runAssertions) 
+import Prelude hiding ((+))
+
+(+) :: Num a => a -> a -> a
+a + b = a - (-b)
+
+main :: IO ()
+main = runAssertions $
+  [ ("2 + 2 = 4", 2 + 2 == 4)
+  ]
diff --git a/test/fixtures/Mixed.hs b/test/fixtures/Mixed.hs
new file mode 100644
--- /dev/null
+++ b/test/fixtures/Mixed.hs
@@ -0,0 +1,11 @@
+import Test.Assert (runAssertions) 
+import Prelude hiding ((+))
+
+(+) :: Num a => a -> a -> a
+a + b = a - (-b)
+
+main :: IO ()
+main = runAssertions $
+  [ ("2 + 2 = 4", 2 + 2 == 4)
+  , ("3 + 2 = 4", 3 + 2 == 4)
+  ]
diff --git a/test/fixtures/Red.hs b/test/fixtures/Red.hs
new file mode 100644
--- /dev/null
+++ b/test/fixtures/Red.hs
@@ -0,0 +1,10 @@
+import Test.Assert (runAssertions) 
+import Prelude hiding ((+))
+
+(+) :: Num a => a -> a -> a
+a + b = a - (-b)
+
+main :: IO ()
+main = runAssertions $
+  [ ("3 + 2 = 4", 3 + 2 == 4)
+  ]
