diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
 All notable changes to this project will be documented in this file.
 This project adheres to [Semantic Versioning](http://semver.org/).
 
+## [0.4.0] - 2015-12-19
+### Added
+- Support for combining `SassValues` (new in hlibsass 0.1.5)
+
+### Changed
+- Requires hlibsass version 0.1.5
+- `SassValue` derives `Show`
+
 ## [0.3.0] - 2015-07-10
 ### Added
 - Support for a `ByteString` result (thanks to [Andy
@@ -33,3 +41,4 @@
 
 [0.2.0]: https://github.com/jakubfijalkowski/hsass/compare/v0.1.0...v0.2.0
 [0.3.0]: https://github.com/jakubfijalkowski/hsass/compare/v0.2.0...v0.3.0
+[0.4.0]: https://github.com/jakubfijalkowski/hsass/compare/v0.3.0...v0.4.0
diff --git a/Text/Sass/Values.hs b/Text/Sass/Values.hs
--- a/Text/Sass/Values.hs
+++ b/Text/Sass/Values.hs
@@ -28,4 +28,4 @@
                 | SassNull -- ^ Null value.
                 | SassWarning String -- ^ Warning with message.
                 | SassError String -- ^ Error with message.
-                deriving (Eq)
+                deriving (Eq, Show)
diff --git a/Text/Sass/Values/Utils.hs b/Text/Sass/Values/Utils.hs
new file mode 100644
--- /dev/null
+++ b/Text/Sass/Values/Utils.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE BangPatterns #-}
+-- | Provides utility functions for working with 'SassValues'
+module Text.Sass.Values.Utils
+  (
+    combineSassValues
+  , Lib.SassOp (..)
+  ) where
+
+import qualified Bindings.Libsass as Lib
+
+import System.IO.Unsafe
+
+import Text.Sass.Values
+import Text.Sass.Values.Internal
+
+-- | Combines two 'SassValue's using specified operator.
+-- |
+-- | Uses 'Lib.sass_value_op'.
+combineSassValues :: Lib.SassOp -- ^ Operator.
+                  -> SassValue  -- ^ First value.
+                  -> SassValue  -- ^ Second value.
+                  -> SassValue  -- ^ Resulting value.
+combineSassValues op val1 val2 = unsafePerformIO $ do
+    native1 <- toNativeValue val1
+    native2 <- toNativeValue val2
+    combined <- Lib.sass_value_op (fromIntegral $ fromEnum op) native1 native2
+    !result <- fromNativeValue combined
+    deleteNativeValue native1
+    deleteNativeValue native2
+    deleteNativeValue combined
+    return result
diff --git a/hsass.cabal b/hsass.cabal
--- a/hsass.cabal
+++ b/hsass.cabal
@@ -1,5 +1,5 @@
 name:                hsass
-version:             0.3.0
+version:             0.4.0
 license:             MIT
 license-file:        LICENSE
 author:              Jakub Fijałkowski <fiolek94@gmail.com>
@@ -44,10 +44,11 @@
     , Text.Sass.Functions.Internal
     , Text.Sass.Options.Internal
     , Text.Sass.Values.Internal
+    , Text.Sass.Values.Utils
     , Text.Sass.Utils
   build-depends:
       base               >= 4.7 && < 5
-    , hlibsass           >= 0.1.1
+    , hlibsass           >= 0.1.5
     , bytestring         >= 0.10.0
     , data-default-class
     , filepath           >= 1.0
@@ -61,6 +62,12 @@
 test-suite test
   hs-source-dirs:      test
   main-is:             Spec.hs
+  other-modules:
+      Text.Sass.CompilationSpec
+    , Text.Sass.FunctionsSpec
+    , Text.Sass.TestingUtils
+    , Text.Sass.TutorialSpec
+    , Text.Sass.ValuesSpec
   type:                exitcode-stdio-1.0
   ghc-options:         -Wall
   build-depends:
diff --git a/test/Text/Sass/CompilationSpec.hs b/test/Text/Sass/CompilationSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Text/Sass/CompilationSpec.hs
@@ -0,0 +1,122 @@
+module Text.Sass.CompilationSpec where
+
+import           System.IO
+import           System.IO.Temp
+import           Test.Hspec
+import           Text.Sass
+
+import           Data.ByteString.Char8  (pack)
+import           Data.Either            (isLeft, isRight)
+import           Data.Maybe             (isJust)
+import           Text.Sass.TestingUtils
+
+main :: IO ()
+main = hspec spec
+
+importerFunc :: String -> IO [SassImport]
+importerFunc _ = return [makeSourceImport "a { margin: 1px; }"]
+
+importers :: [SassImporter]
+importers = [SassImporter 1 importerFunc]
+
+extendedResultSpec, compilationSpec, errorReportingSpec, spec :: Spec
+spec = do
+    describe "Compilation" compilationSpec
+    describe "Extended compilation" extendedResultSpec
+    describe "Error reporting" errorReportingSpec
+
+compilationSpec = do
+    it "should compile simple source" $
+        compileString "foo { margin: 21px * 2; }" def `shouldReturn`
+            Right "foo {\n  margin: 42px; }\n"
+
+    it "should compile simple source as a bytestring" $
+        compileString "foo { margin: 21px * 2; }" def `shouldReturn`
+            Right (pack "foo {\n  margin: 42px; }\n")
+
+    it "should respect options" $ do
+        let opts = def { sassOutputStyle = SassStyleCompressed }
+        compileString "foo { margin: 21px * 2; }" opts `shouldReturn`
+            Right "foo{margin:42px}\n"
+
+    it "should compile file" $
+        withSystemTempFile "styles.sass" $ \p h -> do
+            hPutStr h "foo { margin: 21px * 2; }"
+            hClose h
+            compileFile p def `shouldReturn` Right "foo {\n  margin: 42px; }\n"
+
+    it "compile file should respect options" $ do
+        let opts = def { sassOutputStyle = SassStyleCompressed }
+        withSystemTempFile "styles.sass" $ \p h -> do
+            hPutStr h "foo { margin: 21px * 2; }"
+            hClose h
+            compileFile p opts `shouldReturn` Right "foo{margin:42px}\n"
+
+extendedResultSpec = do
+    it "should compile simple source" $ do
+        res <- compileString "foo { margin: 21px * 2; }" def
+        res `shouldSatisfy` isRight
+        let Right res' = res
+        resultString res' `shouldBe` "foo {\n  margin: 42px; }\n"
+
+    it "should compile simple source as a bytestring" $ do
+        res <- compileString "foo { margin: 21px * 2; }" def
+        res `shouldSatisfy` isRight
+        let Right res' = res
+        resultString res' `shouldBe` (pack "foo {\n  margin: 42px; }\n")
+
+    it "should report correct includes when available" $ do
+        let opts = def { sassImporters = Just importers }
+        Right res <- compileString "@import '_abc';" opts :: ExtendedResult
+        resultIncludes res `shouldReturn` [ "_abc" ]
+
+    it "should report no includes when unavailable" $ do
+        Right res <- compileString "foo { margin: 1px; }" def :: ExtendedResult
+        resultIncludes res `shouldReturn` [ ]
+
+    it "should retrieve source map if available" $ do
+        let opts = def { sassSourceMapFile = Just "abc.css" }
+        Right res <- compileString "foo { margin: 1px; }" opts :: ExtendedResult
+        m <- resultSourcemap res
+        m `shouldSatisfy` isJust
+        let Just m' = m
+        m' `shouldSatisfy` (not . null)
+
+    it "should return Nothing is source map if not available" $ do
+        Right res <- compileString "foo { margin: 1px; }" def :: ExtendedResult
+        resultSourcemap res `shouldReturn` Nothing
+
+errorReportingSpec = do
+    it "string compilation should report error on invalid code" $
+        (compileString "inv mark" def :: StringResult)
+            `returnShouldSatisfy` isLeft
+
+    it "file compilation should report error on invalid code" $
+        withSystemTempFile "styles.sass" $ \p h -> do
+            hPutStr h "!@# !@##  ## #"
+            hClose h
+            (compileFile p def :: StringResult) `returnShouldSatisfy` isLeft
+
+    it "should contain line" $ do
+        (Left r) <- compileString "invalid mark" def :: StringResult
+        errorLine r `shouldReturn` 1
+
+    it "should contain column" $ do
+        (Left r) <- compileString "body { !! }" def :: StringResult
+        errorColumn r `shouldReturn` 7
+
+    it "should contain description" $ do
+        (Left r) <- compileString "body { !! }" def :: StringResult
+        errorText r `returnShouldSatisfy` (not . null)
+
+    it "should contain message" $ do
+        (Left r) <- compileString "body { !! }" def :: StringResult
+        errorMessage r `returnShouldSatisfy` (not . null)
+
+    it "should contain Json description" $ do
+        (Left r) <- compileString "body { !! }" def :: StringResult
+        errorJson r `returnShouldSatisfy` (not . null)
+
+    it "should contain file path" $ do
+        (Left r) <- compileString "body { !! }" def :: StringResult
+        errorFile r `returnShouldSatisfy` (not . null)
diff --git a/test/Text/Sass/FunctionsSpec.hs b/test/Text/Sass/FunctionsSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Text/Sass/FunctionsSpec.hs
@@ -0,0 +1,65 @@
+module Text.Sass.FunctionsSpec where
+
+import           Test.Hspec
+import           Text.Sass
+
+fooFunction :: SassValue -> IO SassValue
+fooFunction _ = return $ SassNumber 1 "px"
+
+barFunction :: SassValue -> IO SassValue
+barFunction (SassList [SassString "a"] _) = return $ SassNumber 1 "px"
+barFunction _ = return $ SassError "invalid arguments"
+
+functions :: [SassFunction]
+functions =
+  [ SassFunction "foo()"   fooFunction
+  , SassFunction "bar($n)" barFunction
+  ]
+
+inclContent :: String
+inclContent = "a {\n  margin: 1px; }\n"
+
+altInclContent :: String
+altInclContent = "b {\n  margin: 5px; }\n"
+
+headerFunction :: String -> IO [SassImport]
+headerFunction _ = return [makeSourceImport inclContent]
+
+headers :: [SassImporter]
+headers = [SassImporter 1 headerFunction]
+
+importFunction :: String -> IO [SassImport]
+importFunction "_imp" = return [makeSourceImport inclContent]
+importFunction _      = return [makeSourceImport altInclContent]
+
+importers :: [SassImporter]
+importers = [SassImporter 1 importFunction]
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+    it "should call simple function" $ do
+        let opts = def { sassFunctions = Just functions }
+        compileString "a { margin: foo(); }" opts `shouldReturn`
+            Right "a {\n  margin: 1px; }\n"
+
+    it "should correctly pass arguments to function" $ do
+        let opts = def { sassFunctions = Just functions }
+        compileString "a { margin: bar('a'); }" opts `shouldReturn`
+            Right "a {\n  margin: 1px; }\n"
+
+    it "should correctly inject header" $ do
+        let opts = def { sassHeaders = Just headers }
+        compileString "a { margin : 1px; }" opts `shouldReturn`
+            Right (inclContent ++ "\na {\n  margin: 1px; }\n")
+
+    it "should call importers" $ do
+        let opts = def { sassImporters = Just importers }
+        compileString "@import '_imp';" opts `shouldReturn` Right inclContent
+
+    it "should pass import name to importers" $ do
+        let opts = def { sassImporters = Just importers }
+        compileString "@import 'other';" opts `shouldReturn` Right altInclContent
+
diff --git a/test/Text/Sass/TestingUtils.hs b/test/Text/Sass/TestingUtils.hs
new file mode 100644
--- /dev/null
+++ b/test/Text/Sass/TestingUtils.hs
@@ -0,0 +1,8 @@
+module Text.Sass.TestingUtils where
+
+import           Test.Hspec
+
+-- | @a `returnShouldSatisfy` p@ asserts that the action @a@ returns value that
+--   satisfies predicate @p@.
+returnShouldSatisfy :: (Show a, Eq a) => IO a -> (a -> Bool) -> Expectation
+v `returnShouldSatisfy` p = v >>= (`shouldSatisfy` p)
diff --git a/test/Text/Sass/TutorialSpec.hs b/test/Text/Sass/TutorialSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Text/Sass/TutorialSpec.hs
@@ -0,0 +1,82 @@
+module Text.Sass.TutorialSpec where
+
+import           Control.Concurrent.MVar
+import           Test.Hspec
+import           Text.Sass
+
+max3 :: SassValue -> IO SassValue
+max3 (SassList (SassNumber a _:SassNumber b _:SassNumber c _:_) _) =
+    return $ SassNumber (max a $ max b c) "px"
+max3 _ = return $ SassError "invalid arguments"
+
+max3sig :: SassFunction
+max3sig = SassFunction "max3($a, $b, $c)" max3
+
+warn :: MVar String -> SassValue -> IO SassValue
+warn m (SassList (SassString s:_) _) = do
+    putMVar m s
+    return $ SassString "warn!"
+warn _ _ = return $ SassString "invalid arguments"
+
+warnSig :: MVar String -> SassFunction
+warnSig = SassFunction "@warn" . warn
+
+header :: String -> IO [SassImport]
+header src = return [makeSourceImport $ "$file: " ++ src ++ ";"]
+
+headerSig :: SassImporter
+headerSig = SassImporter 1 header
+
+importer1 :: String -> IO [SassImport]
+importer1 src = return [makeSourceImport $ "$file: " ++ src ++ "1;"]
+
+importer2 :: String -> IO [SassImport]
+importer2 src = return [makeSourceImport $ "$file: " ++ src ++ "2;"]
+
+importerSigs :: [SassImporter]
+importerSigs = [SassImporter 0.5 importer1, SassImporter 1 importer2]
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+    describe "max3" $ do
+        it "should return max value" $ do
+            let vals = SassList [SassNumber 1 "", SassNumber 2 "",
+                                 SassNumber 3 ""] SassSeparatorSpace
+            SassNumber v _ <- max3 vals
+            v `shouldBe` 3
+
+        it "should return error on invalid aruments" $ do
+            let vals = SassList [SassString "", SassString "",
+                                 SassNumber 3 ""] SassSeparatorSpace
+            SassError e <- max3 vals
+            e `shouldBe` "invalid arguments"
+
+        it "should be usable by compile" $ do
+            let opts = def { sassFunctions = Just [max3sig] }
+            compileString "foo { margin: max3(1px, 2px, 3px); }" opts
+                `shouldReturn` Right "foo {\n  margin: 3px; }\n"
+
+    describe "warn" $
+        it "should call warn on @warn statement" $ do
+            msg <- newEmptyMVar
+            let opts = def { sassFunctions = Just [warnSig msg] }
+            _ <- compileString "@warn \"message\";" opts :: StringResult
+            tryTakeMVar msg `shouldReturn` Just "message"
+
+    describe "Headers" $
+        it "should inject header into file" $ do
+            let opts = def {
+                sassHeaders = Just [headerSig]
+              , sassInputPath = Just "path"
+            }
+            compileString "foo { prop: $file; }" opts `shouldReturn`
+                Right "foo {\n  prop: path; }\n"
+
+    describe "Importers" $
+        it "should inject import with higher priority" $ do
+            let opts = def { sassImporters = Just importerSigs }
+            compileString "@import \"file\";\nfoo { prop: $file; }" opts
+                `shouldReturn` Right "foo {\n  prop: file2; }\n"
diff --git a/test/Text/Sass/ValuesSpec.hs b/test/Text/Sass/ValuesSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Text/Sass/ValuesSpec.hs
@@ -0,0 +1,95 @@
+{-# LANGUAGE StandaloneDeriving #-}
+module Text.Sass.ValuesSpec where
+
+import           Test.Hspec
+import           Text.Sass
+import           Text.Sass.Values.Utils
+
+optsWithVal :: SassValue -> SassOptions
+optsWithVal v = def {
+    sassFunctions = Just [SassFunction "foo()" (\_ -> return v)]
+}
+
+testSerialize :: SassValue -> String -> Expectation
+testSerialize v e =
+    let opts = optsWithVal v
+    in compileString "foo { prop: foo(); }" opts `shouldReturn`
+        Right ("foo {\n  prop: " ++ e ++ "; }\n")
+
+fooFunction :: SassValue -> SassValue -> IO SassValue
+fooFunction e (SassList [a] _) = return $ if e == a
+    then a
+    else SassNull
+fooFunction _ _ = error "fooFunction: invalid arguments"
+
+optsWithArg :: SassValue -> SassOptions
+optsWithArg a = def {
+    sassFunctions = Just [SassFunction "foo($a)" (fooFunction a)]
+}
+
+testDeserialize :: SassValue -> String -> Expectation
+testDeserialize a e =
+    let opts = optsWithArg a
+    in compileString ("foo { prop: foo(" ++ e ++ "); }") opts `shouldReturn`
+        Right ("foo {\n  prop: " ++ e ++ "; }\n")
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+    it "should serialize boolean true" $
+        testSerialize (SassBool True) "true"
+
+    it "should serialize boolean false" $
+        testSerialize (SassBool False) "false"
+
+    it "should serialize number" $
+        testSerialize (SassNumber 1 "px") "1px"
+
+    it "should serialize color" $
+        testSerialize (SassColor 1 2 3 0.5) "rgba(1, 2, 3, 0.5)"
+
+    it "should serialize string" $
+        testSerialize (SassString "abcd") "abcd"
+
+    it "should serialize list" $
+        testSerialize
+            (SassList [SassNumber 1 "px", SassNumber 2 "px"]
+             SassSeparatorComma)
+            "1px, 2px"
+
+    it "should serialize map" $ do
+        let map = (SassMap [ (SassString "a", SassString "b")
+                  , (SassNumber 1 "", SassBool True)])
+        let opts = optsWithVal map
+        result <- compileString "@each $key, $val in foo() { #{$key} { val: #{$val} } }" opts
+        result `shouldBe` Right "a {\n  val: b; }\n\n1 {\n  val: true; }\n"
+
+    it "should deserialize boolean true" $
+        testDeserialize (SassBool True) "true"
+
+    it "should deserialize boolean false" $
+        testDeserialize (SassBool False) "false"
+
+    it "should deserialize number" $
+        testDeserialize (SassNumber 1 "px") "1px"
+
+    it "should deserialize color" $
+        testDeserialize (SassColor 1 2 3 0.5) "rgba(1, 2, 3, 0.5)"
+
+    it "should deserialize string" $
+        testDeserialize (SassString "abcd") "abcd"
+
+    it "should deserialize list" $
+        testDeserialize
+            (SassList [SassNumber 1 "px", SassNumber 2 "px"] SassSeparatorSpace)
+            "1px 2px"
+
+    it "should deserialize map" $
+        pendingWith "Libsass does not allow maps in CSS any more"
+
+    it "should correctly combine two SassValues" $ do
+        let val1 = SassNumber 1.0 ""
+            val2 = SassNumber 2.0 ""
+        combineSassValues SassAdd val1 val2 `shouldBe` SassNumber 3.0 ""
