1{-# OPTIONS_GHC -fprint-potential-instances #-}
3{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE OverloadedLists #-}
7{-# LANGUAGE OverloadedStrings #-}
8{-# LANGUAGE RankNTypes #-}
9{-# LANGUAGE ScopedTypeVariables #-}
10{-# LANGUAGE TypeApplications #-}
12module SchemaSpec (spec, main) where
16import Data.ByteString.Lazy
17import Data.Functor.Identity
20import Data.Schematic.Generator
25import Test.Hspec.SmallCheck
26import Test.SmallCheck as SC
27import Test.SmallCheck.Drivers as SC
28import Test.SmallCheck.Series as SC
32type SchemaExample = 'SchemaObject
33 '[ '("foo", 'SchemaArray '[ 'AEq 1] ('SchemaNumber '[ 'NGt 10]))
34 , '("bar", 'SchemaOptional ('SchemaText '[ 'TEnum '["foo", "bar"]]))]
36type SchemaExample2 = 'SchemaObject
37 '[ '("foo", 'SchemaArray '[ 'AEq 2] ('SchemaText '[ 'TGt 10]))
38 , '("bar", 'SchemaOptional ('SchemaText '[ 'TRegex "[0-9]+"]))]
40jsonExample :: JsonRepr SchemaExample
41jsonExample = withRepr @SchemaExample
42 $ field @"bar" (Just "bar")
47 'Migration "add_field_quuz"
48 '[ 'Diff '[] ('AddKey "quuz" (SchemaNumber '[])) ]
51 'Migration "remove_field_quuz"
52 '[ 'Diff '[] ( 'DeleteKey "quuz") ]
55 'Migration "swap_fields"
56 '[ 'Diff '[ 'PKey "bar" ] ('Update
57 ('SchemaArray '[ 'AEq 1] ('SchemaNumber '[ 'NGt 10])))
58 , 'Diff '[ 'PKey "foo" ] ('Update
59 ('SchemaOptional ('SchemaText '[ 'TEnum '["foo", "bar"]]))) ]
61type Migrations = '[ AddQuuz
65type VersionedJson = 'Versioned SchemaExample Migrations
67migrationList :: MigrationList Identity VersionedJson
69 = (migrateObject (\r -> Identity $ field @"quuz" 42 :& r))
71 -- :&& (migrateObject (\r -> Identity
72 -- $ field @"foo" (r ^. flens (Proxy @"bar") . _Just . optionalRepr)
73 -- :& field @"bar" (r ^. flens (Proxy @"foo") . arrayRepr)
77schemaJson :: ByteString
78schemaJson = "{\"foo\": [13], \"bar\": null}"
80schemaJson2 :: ByteString
81schemaJson2 = "{\"foo\": [3], \"bar\": null}"
83schemaJsonSeries :: Monad m => SC.Series m (JsonRepr SchemaExample)
84schemaJsonSeries = series
86schemaJsonSeries2 :: Monad m => SC.Series m (JsonRepr SchemaExample2)
87schemaJsonSeries2 = series
91 -- it "show/read JsonRepr properly" $
92 -- read (show example) == example
93 it "decode/encode JsonRepr properly" $
94 decode (encode jsonExample) == Just jsonExample
95 it "validates correct representation" $
96 ((decodeAndValidateJson schemaJson) :: ParseResult (JsonRepr SchemaExample))
97 `shouldSatisfy` isValid
98 it "returns decoding error on structurally incorrect input" $
99 ((decodeAndValidateJson "{}") :: ParseResult (JsonRepr SchemaExample))
100 `shouldSatisfy` isDecodingError
101 it "validates incorrect representation" $
102 ((decodeAndValidateJson schemaJson2) :: ParseResult (JsonRepr SchemaExample))
103 `shouldSatisfy` isValidationError
104 -- it "validates versioned json" $ do
105 -- decodeAndValidateVersionedJson (Proxy @VS) schemaJson
106 -- `shouldSatisfy` isValid
107 it "validates versioned json with a migration list" $ do
108 decodeAndValidateVersionedWithPureMList
109 (Proxy @VersionedJson)
112 `shouldSatisfy` isValid
113 it "validates json series" $ property $
114 SC.over schemaJsonSeries $ \x ->
115 isValid (parseAndValidateJson @SchemaExample (toJSON x))
116 it "validates json series 2" $ property $
117 SC.over schemaJsonSeries2 $ \x ->
118 isValid (parseAndValidateJson @SchemaExample2 (toJSON x))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list