/
TestJsonSerde.fs
126 lines (107 loc) · 3.98 KB
/
TestJsonSerde.fs
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
namespace WoofWare.Myriad.Plugins.Test
open System
open System.Collections.Generic
open System.IO
open System.Text
open System.Text.Json
open System.Text.Json.Nodes
open NUnit.Framework
open FsCheck
open FsUnitTyped
open ConsumePlugin
[<TestFixture>]
module TestJsonSerde =
let uriGen : Gen<Uri> =
gen {
let! suffix = Arb.generate<int>
return Uri $"https://example.com/%i{suffix}"
}
let rec innerGen (count : int) : Gen<InnerTypeWithBoth> =
gen {
let! guid = Arb.generate<Guid>
let! mapKeys = Gen.listOf Arb.generate<NonNull<string>>
let mapKeys = mapKeys |> List.map _.Get |> List.distinct
let! mapValues = Gen.listOfLength mapKeys.Length uriGen
let map = List.zip mapKeys mapValues |> Map.ofList
let! concreteDictKeys =
if count > 0 then
Gen.listOf Arb.generate<NonNull<string>>
else
Gen.constant []
let concreteDictKeys =
concreteDictKeys
|> List.map _.Get
|> List.distinct
|> fun x -> List.take (min 3 x.Length) x
let! concreteDictValues =
if count > 0 then
Gen.listOfLength concreteDictKeys.Length (innerGen (count - 1))
else
Gen.constant []
let concreteDict =
List.zip concreteDictKeys concreteDictValues
|> List.map KeyValuePair
|> Dictionary
let! readOnlyDictKeys = Gen.listOf Arb.generate<NonNull<string>>
let readOnlyDictKeys = readOnlyDictKeys |> List.map _.Get |> List.distinct
let! readOnlyDictValues = Gen.listOfLength readOnlyDictKeys.Length (Gen.listOf Arb.generate<char>)
let readOnlyDict = List.zip readOnlyDictKeys readOnlyDictValues |> readOnlyDict
let! dictKeys = Gen.listOf uriGen
let! dictValues = Gen.listOfLength dictKeys.Length Arb.generate<bool>
let dict = List.zip dictKeys dictValues |> dict
return
{
Thing = guid
Map = map
ReadOnlyDict = readOnlyDict
Dict = dict
ConcreteDict = concreteDict
}
}
let outerGen : Gen<JsonRecordTypeWithBoth> =
gen {
let! a = Arb.generate<int>
let! b = Arb.generate<NonNull<string>>
let! c = Gen.listOf Arb.generate<int>
let! depth = Gen.choose (0, 2)
let! d = innerGen depth
let! e = Gen.arrayOf Arb.generate<NonNull<string>>
let! f = Gen.arrayOf Arb.generate<int>
return
{
A = a
B = b.Get
C = c
D = d
E = e |> Array.map _.Get
F = f
}
}
[<Test>]
let ``It just works`` () =
let property (o : JsonRecordTypeWithBoth) : bool =
o
|> JsonRecordTypeWithBoth.toJsonNode
|> fun s -> s.ToJsonString ()
|> JsonNode.Parse
|> JsonRecordTypeWithBoth.jsonParse
|> shouldEqual o
true
property |> Prop.forAll (Arb.fromGen outerGen) |> Check.QuickThrowOnFailure
[<Test>]
let ``Guids are treated just like strings`` () =
let guidStr = "b1e7496e-6e79-4158-8579-a01de355d3b2"
let guid = Guid.Parse guidStr
let node =
{
Thing = guid
Map = Map.empty
ReadOnlyDict = readOnlyDict []
Dict = dict []
ConcreteDict = Dictionary ()
}
|> InnerTypeWithBoth.toJsonNode
node.ToJsonString ()
|> shouldEqual (
sprintf """{"it\u0027s-a-me":"%s","map":{},"readOnlyDict":{},"dict":{},"concreteDict":{}}""" guidStr
)