diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2016-01-10 04:43:42 +0000 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2016-01-10 04:43:42 +0000 |
commit | 6ec3c805ea2cd629a75641530de30ab39a191409 (patch) | |
tree | 9a63c2edbe6834a17a67b055279024b7ec31eb3a /spec | |
parent | 0bb617ff93d242d20e9e63f44664f38a653898d4 (diff) | |
download | thermoprint-6ec3c805ea2cd629a75641530de30ab39a191409.tar thermoprint-6ec3c805ea2cd629a75641530de30ab39a191409.tar.gz thermoprint-6ec3c805ea2cd629a75641530de30ab39a191409.tar.bz2 thermoprint-6ec3c805ea2cd629a75641530de30ab39a191409.tar.xz thermoprint-6ec3c805ea2cd629a75641530de30ab39a191409.zip |
First stab at API
Diffstat (limited to 'spec')
-rw-r--r-- | spec/src/Thermoprint/API.hs | 21 | ||||
-rw-r--r-- | spec/src/Thermoprint/Printout.hs | 28 | ||||
-rw-r--r-- | spec/test/Thermoprint/PrintoutSpec.hs | 17 | ||||
-rw-r--r-- | spec/thermoprint-spec.cabal | 8 | ||||
-rw-r--r-- | spec/thermoprint-spec.nix | 14 |
5 files changed, 82 insertions, 6 deletions
diff --git a/spec/src/Thermoprint/API.hs b/spec/src/Thermoprint/API.hs new file mode 100644 index 0000000..f2ffd02 --- /dev/null +++ b/spec/src/Thermoprint/API.hs | |||
@@ -0,0 +1,21 @@ | |||
1 | {-# LANGUAGE GeneralizedNewtypeDeriving, NoDeriveAnyClass #-} | ||
2 | {-# LANGUAGE TypeOperators, DataKinds #-} | ||
3 | |||
4 | module Thermoprint.API | ||
5 | ( PrinterId(..) | ||
6 | , JobId(..) | ||
7 | , ThermoprintAPI | ||
8 | ) where | ||
9 | |||
10 | import Thermoprint.Printout | ||
11 | |||
12 | import Servant.API | ||
13 | import Data.Aeson | ||
14 | |||
15 | newtype PrinterId = PrinterId Integer | ||
16 | deriving (Show, Eq, FromText, ToText, FromJSON, ToJSON) | ||
17 | |||
18 | newtype JobId = JobId Integer | ||
19 | deriving (Show, Eq, FromText, ToText, FromJSON, ToJSON) | ||
20 | |||
21 | type ThermoprintAPI = "print" :> Capture "printerId" PrinterId :> ReqBody '[JSON] Printout :> Post '[JSON] JobId | ||
diff --git a/spec/src/Thermoprint/Printout.hs b/spec/src/Thermoprint/Printout.hs index 32c403c..d9d9902 100644 --- a/spec/src/Thermoprint/Printout.hs +++ b/spec/src/Thermoprint/Printout.hs | |||
@@ -23,6 +23,9 @@ import Data.ByteString.Lazy (ByteString) | |||
23 | 23 | ||
24 | import GHC.Generics (Generic) | 24 | import GHC.Generics (Generic) |
25 | import Control.DeepSeq (NFData) | 25 | import Control.DeepSeq (NFData) |
26 | import Data.Aeson (FromJSON(..), ToJSON(..), Value(..)) | ||
27 | import qualified Data.Aeson as JSON (encode, decode) | ||
28 | import Data.Aeson.Types (typeMismatch) | ||
26 | 29 | ||
27 | import Test.QuickCheck.Arbitrary (Arbitrary(..), CoArbitrary, genericShrink) | 30 | import Test.QuickCheck.Arbitrary (Arbitrary(..), CoArbitrary, genericShrink) |
28 | import Test.QuickCheck.Modifiers (NonNegative(..)) | 31 | import Test.QuickCheck.Modifiers (NonNegative(..)) |
@@ -32,6 +35,7 @@ import Test.QuickCheck (forAll, Property) | |||
32 | 35 | ||
33 | 36 | ||
34 | import qualified Data.Text.Lazy as TL (split, null, pack, filter, intercalate, map) | 37 | import qualified Data.Text.Lazy as TL (split, null, pack, filter, intercalate, map) |
38 | import qualified Data.Text as T (pack) | ||
35 | import Data.Char (isSpace) | 39 | import Data.Char (isSpace) |
36 | 40 | ||
37 | import Data.Monoid (Monoid(..), (<>)) | 41 | import Data.Monoid (Monoid(..), (<>)) |
@@ -42,7 +46,13 @@ import Data.Sequence as Seq (fromList, null, singleton) | |||
42 | 46 | ||
43 | import Data.Function (on) | 47 | import Data.Function (on) |
44 | 48 | ||
45 | import Data.Foldable (toList) | 49 | import Data.Foldable (toList, fold) |
50 | |||
51 | import Data.Encoding (encodeLazyByteStringExplicit, decodeLazyByteString) | ||
52 | import Data.Encoding.UTF8 | ||
53 | import qualified Data.ByteString.Base64.Lazy as Base64 (encode, decode) | ||
54 | |||
55 | import Prelude hiding (fold) | ||
46 | 56 | ||
47 | 57 | ||
48 | -- | A 'Printout' is a sequence of visually seperated 'Paragraph's | 58 | -- | A 'Printout' is a sequence of visually seperated 'Paragraph's |
@@ -58,11 +68,23 @@ data Chunk = Cooked Block -- ^ text semantically structured to be rendered in ac | |||
58 | | Raw ByteString -- ^ direct instructions to the printer | 68 | | Raw ByteString -- ^ direct instructions to the printer |
59 | deriving (Generic, NFData, Show, CoArbitrary) | 69 | deriving (Generic, NFData, Show, CoArbitrary) |
60 | 70 | ||
71 | instance FromJSON Chunk where | ||
72 | parseJSON s@(String _) = Raw <$> ((either fail return . decodeBase64) =<< parseJSON s) | ||
73 | where | ||
74 | decodeBase64 :: String -> Either String ByteString | ||
75 | decodeBase64 s = (either (Left . show) Right . encodeLazyByteStringExplicit UTF8Strict $ s) >>= Base64.decode | ||
76 | parseJSON o@(Object _) = Cooked <$> parseJSON o | ||
77 | parseJSON v = typeMismatch "Chunk" v | ||
78 | |||
79 | instance ToJSON Chunk where | ||
80 | toJSON (Raw bs) = String . T.pack . decodeLazyByteString UTF8Strict . Base64.encode $ bs | ||
81 | toJSON (Cooked block) = toJSON block | ||
82 | |||
61 | -- | 'Block' is the entry point for our structured document format | 83 | -- | 'Block' is the entry point for our structured document format |
62 | data Block = Line Line -- ^ a single 'Line' of text | 84 | data Block = Line Line -- ^ a single 'Line' of text |
63 | | VSpace Integer -- ^ vertical space of height equivalent to 'Integer' lines | 85 | | VSpace Integer -- ^ vertical space of height equivalent to 'Integer' lines |
64 | | NewlSep (Seq Block) -- ^ A sequence of 'Block's seperated by newlines | 86 | | NewlSep (Seq Block) -- ^ A sequence of 'Block's seperated by newlines |
65 | deriving (Generic, NFData, Show, CoArbitrary) | 87 | deriving (Generic, NFData, Show, CoArbitrary, FromJSON, ToJSON) |
66 | 88 | ||
67 | {- | A 'Line' is one of: | 89 | {- | A 'Line' is one of: |
68 | 90 | ||
@@ -75,7 +97,7 @@ We don't export all constructors and instead encourage the use of 'text'. | |||
75 | data Line = Word Text | 97 | data Line = Word Text |
76 | | HSpace Integer | 98 | | HSpace Integer |
77 | | SpaceSep (Seq Line) | 99 | | SpaceSep (Seq Line) |
78 | deriving (Generic, NFData, Show, CoArbitrary) | 100 | deriving (Generic, NFData, Show, CoArbitrary, FromJSON, ToJSON) |
79 | 101 | ||
80 | instance Monoid Block where | 102 | instance Monoid Block where |
81 | mempty = NewlSep mempty | 103 | mempty = NewlSep mempty |
diff --git a/spec/test/Thermoprint/PrintoutSpec.hs b/spec/test/Thermoprint/PrintoutSpec.hs index 5a48496..b92d76a 100644 --- a/spec/test/Thermoprint/PrintoutSpec.hs +++ b/spec/test/Thermoprint/PrintoutSpec.hs | |||
@@ -1,9 +1,26 @@ | |||
1 | {-# LANGUAGE StandaloneDeriving #-} | ||
2 | |||
1 | module Thermoprint.PrintoutSpec (spec) where | 3 | module Thermoprint.PrintoutSpec (spec) where |
2 | 4 | ||
3 | import Test.Hspec | 5 | import Test.Hspec |
4 | import Test.Hspec.QuickCheck (prop) | 6 | import Test.Hspec.QuickCheck (prop) |
5 | import Thermoprint.Printout | 7 | import Thermoprint.Printout |
6 | 8 | ||
9 | import Data.Aeson (fromJSON, ToJSON(..), Result(..)) | ||
10 | import Data.Function (on) | ||
11 | |||
12 | import Control.DeepSeq (($!!), force) | ||
13 | |||
14 | -- Equality via cotext on Block | ||
15 | instance Eq Block where | ||
16 | (==) = (==) `on` cotext | ||
17 | -- Structural equality for Chunk | ||
18 | deriving instance Eq Chunk | ||
19 | |||
7 | spec :: Spec | 20 | spec :: Spec |
8 | spec = do | 21 | spec = do |
9 | prop "prop_text" prop_text | 22 | prop "prop_text" prop_text |
23 | prop "json" prop_json | ||
24 | where | ||
25 | prop_json :: Printout -> Bool | ||
26 | prop_json p = force $ (== Success p) . fromJSON . toJSON $!! p | ||
diff --git a/spec/thermoprint-spec.cabal b/spec/thermoprint-spec.cabal index c4599c8..426244e 100644 --- a/spec/thermoprint-spec.cabal +++ b/spec/thermoprint-spec.cabal | |||
@@ -19,6 +19,7 @@ cabal-version: >=1.10 | |||
19 | library | 19 | library |
20 | hs-source-dirs: src | 20 | hs-source-dirs: src |
21 | exposed-modules: Thermoprint.Printout | 21 | exposed-modules: Thermoprint.Printout |
22 | , Thermoprint.API | ||
22 | -- other-modules: | 23 | -- other-modules: |
23 | -- other-extensions: | 24 | -- other-extensions: |
24 | extensions: DeriveGeneric | 25 | extensions: DeriveGeneric |
@@ -33,6 +34,10 @@ library | |||
33 | , quickcheck-instances >=0.3.11 && <4 | 34 | , quickcheck-instances >=0.3.11 && <4 |
34 | , Cabal >=1.22.4 && <2 | 35 | , Cabal >=1.22.4 && <2 |
35 | , cabal-test-quickcheck >=0.1.6 && <1 | 36 | , cabal-test-quickcheck >=0.1.6 && <1 |
37 | , servant >=0.4.4 && <1 | ||
38 | , aeson >=0.9.0 && <1 | ||
39 | , base64-bytestring >=1.0.0 && <2 | ||
40 | , encoding >=0.8 && <1 | ||
36 | -- hs-source-dirs: | 41 | -- hs-source-dirs: |
37 | default-language: Haskell2010 | 42 | default-language: Haskell2010 |
38 | 43 | ||
@@ -44,4 +49,5 @@ Test-Suite tests | |||
44 | , thermoprint-spec -any | 49 | , thermoprint-spec -any |
45 | , hspec >=2.2.1 && <3 | 50 | , hspec >=2.2.1 && <3 |
46 | , QuickCheck >=2.8.1 && <3 | 51 | , QuickCheck >=2.8.1 && <3 |
47 | , quickcheck-instances >=0.3.11 && <4 \ No newline at end of file | 52 | , quickcheck-instances >=0.3.11 && <4 |
53 | , aeson >=0.9.0 && <1 \ No newline at end of file | ||
diff --git a/spec/thermoprint-spec.nix b/spec/thermoprint-spec.nix index 82f018a..ea903ba 100644 --- a/spec/thermoprint-spec.nix +++ b/spec/thermoprint-spec.nix | |||
@@ -1,9 +1,19 @@ | |||
1 | { mkDerivation, base, bytestring, containers, stdenv, text, QuickCheck, quickcheck-instances, cabal-test-quickcheck, hspec }: | 1 | { mkDerivation, aeson, base, base64-bytestring, bytestring, Cabal |
2 | , cabal-test-quickcheck, containers, deepseq, encoding, hspec | ||
3 | , QuickCheck, quickcheck-instances, servant, stdenv, text | ||
4 | }: | ||
2 | mkDerivation { | 5 | mkDerivation { |
3 | pname = "thermoprint-spec"; | 6 | pname = "thermoprint-spec"; |
4 | version = "1.0.0"; | 7 | version = "1.0.0"; |
5 | src = ./.; | 8 | src = ./.; |
6 | libraryHaskellDepends = [ base bytestring containers text QuickCheck quickcheck-instances cabal-test-quickcheck hspec ]; | 9 | libraryHaskellDepends = [ |
10 | aeson base base64-bytestring bytestring Cabal cabal-test-quickcheck | ||
11 | containers deepseq encoding QuickCheck quickcheck-instances servant | ||
12 | text | ||
13 | ]; | ||
14 | testHaskellDepends = [ | ||
15 | base hspec QuickCheck quickcheck-instances | ||
16 | ]; | ||
7 | homepage = "http://dirty-haskell.org/tags/thermoprint.html"; | 17 | homepage = "http://dirty-haskell.org/tags/thermoprint.html"; |
8 | description = "A specification of the API and the payload datatypes and associated utilities"; | 18 | description = "A specification of the API and the payload datatypes and associated utilities"; |
9 | license = stdenv.lib.licenses.publicDomain; | 19 | license = stdenv.lib.licenses.publicDomain; |