Skip to content

Commit 33eb8e3

Browse files
committed
added unit test for null value suppression
1 parent 01f9d3b commit 33eb8e3

File tree

6 files changed

+82
-5
lines changed

6 files changed

+82
-5
lines changed

Data/Aeson/Encode/Pretty.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ module Data.Aeson.Encode.Pretty (
4848
-- |Serves as an order-preserving (non-)sort function. Re-exported from
4949
-- "Data.Monoid".
5050
compare,
51-
-- |Sort keys in their natural order, i.e. by comparing character codes.
51+
-- |Sort keys in standard "ASCIIbetical" order, i.e. by comparing character codes.
5252
-- Re-exported from the Prelude and "Data.Ord"
5353
keyOrder
5454
) where
@@ -70,7 +70,7 @@ import qualified Data.Vector as V (toList)
7070
data PState = PState { pstIndent :: Int
7171
, pstLevel :: Int
7272
, pstSort :: [(Text, Value)] -> [(Text, Value)]
73-
, pstNullValues :: Bool
73+
, pstNullValues :: Bool -- ^ allow keys with null values in the output
7474
}
7575

7676
data Config = Config
@@ -93,9 +93,9 @@ keyOrder ks = comparing $ \k -> fromMaybe maxBound (elemIndex k ks)
9393

9494

9595
-- |The default configuration: indent by four spaces per level of nesting, do
96-
-- not sort objects by key.
96+
-- not sort objects by key, and preserve keys with null values.
9797
--
98-
-- > defConfig = Config { confIndent = 4, confCompare = mempty }
98+
-- > defConfig = Config { confIndent = 4, confCompare = mempty, confNullValues = True }
9999
defConfig :: Config
100100
defConfig = Config { confIndent = 4, confCompare = mempty, confNullValues = True }
101101

@@ -135,7 +135,7 @@ fromValue st@PState{..} = go
135135
where original_pairs = H.toList m
136136
filtered_pairs = if pstNullValues
137137
then original_pairs
138-
else filter (\(_, v) -> v /= Null) original_pairs
138+
else filter (\p -> (snd p) /= Null) original_pairs
139139
go v = Aeson.encodeToTextBuilder v
140140

141141
fromCompound :: PState

aeson-pretty.cabal

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,27 @@ executable aeson-pretty
6767
ghc-options: -Wall
6868
ghc-prof-options: -auto-all
6969

70+
test-suite aeson-pretty-tests
71+
hs-source-dirs: test/src
72+
main-is: RunTest.hs
73+
74+
type: exitcode-stdio-1.0
75+
build-depends:
76+
aeson >= 0.6,
77+
aeson-pretty,
78+
base == 4.*,
79+
bytestring >= 0.9,
80+
containers,
81+
filepath,
82+
HUnit,
83+
MissingH,
84+
test-framework,
85+
test-framework-hunit,
86+
utf8-string
87+
88+
ghc-options: -Wall
89+
ghc-prof-options: -auto-all
90+
7091
source-repository head
7192
type: git
7293
location: http://github.com/informatikr/aeson-pretty

test/data/suppress-nulls/input.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"bar": null, "foo": "blah"}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"bar": null,
3+
"foo": "blah"
4+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"foo": "blah"
3+
}

test/src/RunTest.hs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{-# LANGUAGE OverloadedStrings #-}
2+
3+
import Test.Framework
4+
import Test.Framework.Providers.HUnit
5+
6+
import Data.Aeson
7+
import Data.Aeson.Encode.Pretty
8+
import qualified Data.ByteString.Lazy as B
9+
import qualified Data.ByteString.Lazy.UTF8 as U (toString)
10+
import Data.Map (Map)
11+
import Test.HUnit (assertEqual)
12+
import System.FilePath.Posix
13+
import Data.String.Utils (rstrip)
14+
15+
testDataDir :: FilePath
16+
testDataDir = "test/data/suppress-nulls"
17+
18+
eitherDecodeMap :: IO (Map String (Maybe String))
19+
eitherDecodeMap = do
20+
d <- eitherDecode <$> B.readFile (testDataDir </> "input.json")
21+
case d of
22+
Left err -> error $ "ERROR: " ++ err
23+
Right val -> return val
24+
25+
26+
prettifyMap :: Bool -> Map String (Maybe String) -> String
27+
prettifyMap s m = U.toString $ encodePretty' (Config 4 compare s) m
28+
29+
30+
testEquality :: Bool -> FilePath -> IO ()
31+
testEquality suppress data_filename = do
32+
vals <- eitherDecodeMap
33+
let pretty_output_computed = prettifyMap suppress vals
34+
reference_output_file_content <- readFile $ testDataDir </> data_filename
35+
let pretty_output_expected = rstrip $ reference_output_file_content
36+
37+
assertEqual "Checking equality..." pretty_output_expected pretty_output_computed
38+
39+
40+
tests = [
41+
testGroup "Null value suppression" [
42+
testCase "nulls-allowed" $ testEquality True "null-values-allowed.json"
43+
, testCase "nulls-suppressed" $ testEquality False "null-values-suppressed.json"
44+
]
45+
]
46+
47+
48+
main = defaultMain tests

0 commit comments

Comments
 (0)