-
Notifications
You must be signed in to change notification settings - Fork 46
/
Main.purs
142 lines (126 loc) · 4.57 KB
/
Main.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
module Test.Main where
import Prelude
import Control.Monad.Aff (Aff)
import Control.Monad.Eff (Eff)
import Data.Argonaut.Core (Json)
import Data.Argonaut.Parser (jsonParser)
import Data.Either (Either(..), either, fromLeft, isRight)
import Data.Foreign (ForeignError(..), MultipleErrors)
import Data.Foreign.NullOrUndefined (NullOrUndefined)
import Data.List (List(..))
import Data.List.NonEmpty (NonEmptyList(..))
import Data.Maybe (Maybe)
import Data.NonEmpty (NonEmpty(..))
import Data.Nullable (Nullable)
import Data.StrMap (StrMap)
import Data.Variant (Variant)
import Partial.Unsafe (unsafePartial)
import Simple.JSON (class ReadForeign, class WriteForeign, readJSON, writeJSON)
import Test.Spec (describe, it)
import Test.Spec.Assertions (fail, shouldEqual)
import Test.Spec.Reporter (consoleReporter)
import Test.Spec.Runner (RunnerEffects, run)
import Type.Proxy (Proxy(..))
type E a = Either MultipleErrors a
type MyTest =
{ a :: Int
, b :: String
, c :: Boolean
, d :: Array String
}
type MyTestNull =
{ a :: Int
, b :: String
, c :: Boolean
, d :: Array String
, e :: NullOrUndefined (Array String)
}
type MyTestStrMap =
{ a :: Int
, b :: StrMap Int
}
type MyTestMaybe =
{ a :: Maybe String
}
type MyTestManyMaybe =
{ a :: Maybe String
, aNull :: Maybe String
, b :: Maybe Int
, bNull :: Maybe Int
, c :: Maybe Boolean
, cNull :: Maybe Boolean
, d :: Maybe Number
, dNull :: Maybe Number
, e :: Maybe (Array (Maybe String))
, eNull :: Maybe (Array (Maybe String))
}
type MyTestNullable =
{ a :: Nullable String
, b :: Nullable String
}
type MyTestVariant = Variant
( a :: String
, b :: Int
)
roundtrips :: forall a. ReadForeign a => WriteForeign a => Proxy a -> String -> Aff (RunnerEffects ()) Unit
roundtrips _ enc0 = do
let dec0 :: E a
dec0 = readJSON enc0
enc1 = either (const "bad1") writeJSON dec0
json0 :: Either String Json
json0 = jsonParser enc0
json1 :: Either String Json
json1 = jsonParser enc1
dec1 :: E a
dec1 = readJSON enc1
enc2 = either (const "bad2") writeJSON dec1
when (json0 /= json1) $ fail $ "\n\torig: " <> show json0 <> "\n\tenc: " <> show json1
when (enc1 /= enc2) $ fail enc0
main :: Eff (RunnerEffects ()) Unit
main = run [consoleReporter] do
describe "readJSON" do
it "fails with invalid JSON" do
let result = readJSON """
{ "c": 1, "d": 2}
"""
(unsafePartial $ fromLeft result) `shouldEqual`
(NonEmptyList (NonEmpty (ErrorAtProperty "a" (TypeMismatch "Int" "Undefined")) Nil))
isRight (result :: E MyTest) `shouldEqual` false
it "works with missing Maybe fields by setting them to Nothing" do
let result = readJSON "{}"
(writeJSON <$> (result :: E MyTestMaybe)) `shouldEqual` (Right """{"a":null}""")
it "fails with undefined for null with correct error message" do
let result = readJSON """
{ "a": "asdf" }
"""
(unsafePartial $ fromLeft result) `shouldEqual`
(NonEmptyList (NonEmpty (ErrorAtProperty "b" (TypeMismatch "Nullable String" "Undefined")) Nil))
isRight (result :: E MyTestNullable) `shouldEqual` false
describe "roundtrips" do
it "works with proper JSON" $ roundtrips (Proxy :: Proxy MyTest) """
{ "a": 1, "b": "asdf", "c": true, "d": ["A", "B"]}
"""
it "works with JSON lacking NullOrUndefined field" $ roundtrips (Proxy :: Proxy MyTestNull) """
{ "a": 1, "b": "asdf", "c": true, "d": ["A", "B"]}
"""
it "works with JSON containing NullOrUndefined field" $ roundtrips (Proxy :: Proxy MyTestNull) """
{ "a": 1, "b": "asdf", "c": true, "d": ["A", "B"], "e": ["C", "D"]}
"""
it "works with JSON containing StrMap field" $ roundtrips (Proxy :: Proxy MyTestStrMap) """
{ "a": 1, "b": {"asdf": 1, "c": 2} }
"""
it "works with Maybe field and existing value" $ roundtrips (Proxy :: Proxy MyTestMaybe) """
{ "a": "foo" }
"""
it "works with Maybe field and null value" $ roundtrips (Proxy :: Proxy MyTestMaybe) """
{ "a": null }
"""
it "works with many Maybe fields" $ roundtrips (Proxy :: Proxy MyTestManyMaybe) """
{ "a": "str", "aNull": null, "b":1, "bNull": null, "c":true, "cNull":null, "d":1.1, "dNull":null, "e":["str1", "str2", null], "eNull": null }
"""
it "works with Nullable" $ roundtrips (Proxy :: Proxy MyTestNullable) """
{ "a": null, "b": "a" }
"""
it "works with Variant" $ roundtrips (Proxy :: Proxy MyTestVariant) """
{ "type": "b", "value": 123 }
"""