hspec-attoparsec-0.1.0.2/ 0000755 0000000 0000000 00000000000 12503264210 013276 5 ustar 00 0000000 0000000 hspec-attoparsec-0.1.0.2/hspec-attoparsec.cabal 0000644 0000000 0000000 00000003161 12503264210 017530 0 ustar 00 0000000 0000000 name: hspec-attoparsec
version: 0.1.0.2
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-2015 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 hspec-attoparsec-0.1.0.2/LICENSE 0000644 0000000 0000000 00000002776 12503264210 014317 0 ustar 00 0000000 0000000 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.
hspec-attoparsec-0.1.0.2/Setup.hs 0000644 0000000 0000000 00000000056 12503264210 014733 0 ustar 00 0000000 0000000 import Distribution.Simple
main = defaultMain
hspec-attoparsec-0.1.0.2/src/ 0000755 0000000 0000000 00000000000 12503264210 014065 5 ustar 00 0000000 0000000 hspec-attoparsec-0.1.0.2/src/Test/ 0000755 0000000 0000000 00000000000 12503264210 015004 5 ustar 00 0000000 0000000 hspec-attoparsec-0.1.0.2/src/Test/Hspec/ 0000755 0000000 0000000 00000000000 12503264210 016046 5 ustar 00 0000000 0000000 hspec-attoparsec-0.1.0.2/src/Test/Hspec/Attoparsec.hs 0000644 0000000 0000000 00000010246 12503264210 020512 0 ustar 00 0000000 0000000 {-# LANGUAGE OverloadedStrings,
FlexibleContexts #-}
-- |
-- 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 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:
--
-- > "" ~> 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
isLeft :: Either a b -> Bool
isLeft (Left _) = True
isLeft _ = False
isRight :: Either a b -> Bool
isRight (Right _) = True
isRight _ = False
-- | 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
hspec-attoparsec-0.1.0.2/src/Test/Hspec/Attoparsec/ 0000755 0000000 0000000 00000000000 12503264210 020153 5 ustar 00 0000000 0000000 hspec-attoparsec-0.1.0.2/src/Test/Hspec/Attoparsec/Source.hs 0000644 0000000 0000000 00000006300 12503264210 021746 0 ustar 00 0000000 0000000 {-# 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/.
--
-- > -- "" fed to an HTML parser
-- > "Go to foo" ~> 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
hspec-attoparsec-0.1.0.2/tests/ 0000755 0000000 0000000 00000000000 12503264210 014440 5 ustar 00 0000000 0000000 hspec-attoparsec-0.1.0.2/tests/Spec.hs 0000644 0000000 0000000 00000000054 12503264210 015665 0 ustar 00 0000000 0000000 {-# OPTIONS_GHC -F -pgmF hspec-discover #-}