packages feed

digestive-functors-aeson 1.0.1 → 1.0.2

raw patch · 5 files changed

+115/−19 lines, 5 filesdep +HUnitdep +digestive-functors-aesondep +mtldep ~aesondep ~aeson-lensdep ~digestive-functorssetup-changedPVP ok

version bump matches the API change (PVP)

Dependencies added: HUnit, digestive-functors-aeson, mtl, test-framework, test-framework-hunit

Dependency ranges changed: aeson, aeson-lens, digestive-functors

API changes (from Hackage documentation)

+ Text.Digestive.Aeson: jsonErrors :: ToJSON a => View a -> Value

Files

+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
− Setup.lhs
@@ -1,7 +0,0 @@-#!/usr/bin/runhaskell-> module Main (main) where--> import Distribution.Simple--> main :: IO ()-> main = defaultMain
digestive-functors-aeson.cabal view
@@ -1,6 +1,6 @@ name: digestive-functors-aeson category: Web, JSON-version: 1.0.1+version: 1.0.2 license: GPL-3 license-file: LICENSE author: Oliver Charles@@ -14,6 +14,8 @@ description:   This package allows you to run a form created by digestive functors against a   JSON document that has been parsed by Aeson.+  .+  For changes, please see http://github.com/ocharles/changelog.md  source-repository head   type: git@@ -25,12 +27,27 @@     Text.Digestive.Aeson   build-depends:     aeson >= 0.6,-    aeson-lens >= 0.4.0.1,+    aeson-lens >= 0.4.1.0,     base >= 4.5 && < 4.7,-    digestive-functors >= 0.5,+    digestive-functors >= 0.5 && < 0.6,     lens >= 3.0,     safe >= 0.3.3,     text >= 0.11   hs-source-dirs: src   ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -O2                -fno-warn-orphans -fno-warn-unused-do-bind++test-suite tests+  type: exitcode-stdio-1.0+  hs-source-dirs: test+  main-is: Tests.hs+  build-depends:+    aeson,+    base >= 4.5 && < 4.7,+    digestive-functors >= 0.5,+    digestive-functors-aeson ==1.0.2,+    HUnit >= 1.2,+    mtl,+    test-framework >= 0.6,+    test-framework-hunit,+    text >= 0.11
src/Text/Digestive/Aeson.hs view
@@ -2,13 +2,16 @@ {-# LANGUAGE OverloadedStrings #-} -- | Run digestive-functors forms against JSON. module Text.Digestive.Aeson-    ( digestJSON ) where+    ( digestJSON+    , jsonErrors+    ) where -import Control.Lens-import Data.Aeson (Value(..))-import Data.Aeson.Lens-import Safe-import Text.Digestive+import           Control.Lens+import           Data.Aeson (ToJSON(toJSON), Value(..), object)+import           Data.Aeson.Lens+import           Data.Maybe (fromMaybe)+import           Safe+import           Text.Digestive  import qualified Data.Text as T @@ -39,9 +42,6 @@         jsonEnv v p = return . maybe [] jsonToText $           Just v ^. pathToLens (filter (not . T.null) p) -        pathToLens = foldl (.) id . map pathElem-        pathElem p = maybe (key p) nth (readMay $ T.unpack p)-         jsonToText (String s) = [TextInput s]         jsonToText (Bool b)   = showPack b         jsonToText (Number n) = showPack n@@ -50,3 +50,31 @@         jsonToText (Array _)  = []          showPack = return . TextInput . T.pack . show+++--------------------------------------------------------------------------------+{-| Takes a 'View' and displays any errors in a hierachical format that matches+the expected input.++Example:++>     > jsonErrors myForm+>     {"person":{"name":"This field is required"}}+-}+jsonErrors :: ToJSON a => View a -> Value+jsonErrors = fromMaybe (error "Constructing error tree failed!") .+    foldl encodeError (Just $ object []) . viewErrors+  where+    encodeError json (path, message) =+      json & pathToLens path .~ Just (toJSON message)+++--------------------------------------------------------------------------------+pathToLens :: Functor f+           => [T.Text]+           -> (Maybe Value -> f (Maybe Value))+           -> Maybe Value+           -> f (Maybe Value)+pathToLens = foldl (.) id . map pathElem+  where+    pathElem p = maybe (key p) nth (readMay $ T.unpack p)
+ test/Tests.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import           Control.Applicative+import           Control.Monad.Identity (runIdentity)+import           Data.Aeson (decode)+import           Data.Text+import           Test.Framework (Test, defaultMain, testGroup)+import           Test.Framework.Providers.HUnit (testCase)+import           Test.HUnit ((@?=))+import           Text.Digestive (Form, (.:), check, text)+import           Text.Digestive.Aeson (digestJSON, jsonErrors)++import qualified Data.Text as T++--------------------------------------------------------------------------------+tests :: [Test]+tests = [ testPokemon+        ]+++--------------------------------------------------------------------------------+data Pokemon = Pokemon { pokemonName :: Text }+  deriving (Eq, Show)+++testPokemon :: Test+testPokemon = testGroup "Pokemon tests" [ testPokemonOk, testPokemonInvalid ]+  where+    pokeForm :: Monad m => Form Text m Pokemon+    pokeForm = Pokemon <$> "name" .: nonEmptyText+      where+        nonEmptyText = check "Name cannot be empty" (not . T.null) $+                         text Nothing++    testPokemonOk = testCase "Submit pokeForm with valid data" $+        Just expected @?= (runIdentity $ snd <$> digestJSON pokeForm json)+      where+        (Just json) = decode "{\"name\":\"Pikachu\"}"+        expected = Pokemon { pokemonName = "Pikachu" }++    testPokemonInvalid =+        let (v, r) = runIdentity $ digestJSON pokeForm json+        in testGroup "Submit pokeForm with invalid data/check error view"+             [ testCase "Failed validation" $ r @?= Nothing+             , testCase "jsonErrors shows correct errors" $ jsonErrors v @?= errors+             ]+      where+        (Just json) = decode "{\"name\":\"\"}"+        (Just errors) = decode "{\"name\":\"Name cannot be empty\"}"+        expected = Pokemon { pokemonName = "Pikachu" }+++--------------------------------------------------------------------------------+main :: IO ()+main = defaultMain tests