зеркало из https://github.com/microsoft/fsharplu.git
425 строки
23 KiB
Forth
425 строки
23 KiB
Forth
module Microsoft.FSharpLu.Json.Tests
|
|
|
|
open Microsoft.VisualStudio.TestTools.UnitTesting
|
|
open FsCheck
|
|
open Microsoft.FSharpLu.Json
|
|
open Newtonsoft.Json
|
|
|
|
open Compact.CamelCaseNoFormatting
|
|
|
|
type WithFields = SomeField of int * int
|
|
type SimpleDu = Foo | FooBar | Bar
|
|
type ComplexDu = ComplexDu of WithFields | SimpleDU | AString of string
|
|
type 'a RecursiveList = RecListLeaf of 'a | RecListCons of 'a RecursiveList
|
|
type OptionOfBase = int option
|
|
type OptionOfDu = SimpleDu option
|
|
type Color = Red | Blue
|
|
type Shape = Circle of int * int | Rectangle
|
|
type 'a Tree = Leaf of 'a | Node of 'a Tree * 'a Tree
|
|
type 'a Test = Case1 | Case2 of int | Case3 of int * string * 'a
|
|
type MapType = Map<string,Color>
|
|
type 'a NestedOptions = 'a option option option option
|
|
type ConsecutiveUppercaseRecord = { BAR : int ; BAZNumber : int }
|
|
type ConsecutiveUppercaseDu = FOO | FOOWithRecord of ConsecutiveUppercaseRecord
|
|
type RecordWithDU = { du: ComplexDu }
|
|
|
|
type 'a Wrapper = { WrappedField : 'a }
|
|
type NestedStructure = { subField : int }
|
|
type NestedOptionStructure = { field : NestedStructure option }
|
|
|
|
type SomeTupleType = int * string list * int * int64 * OptionOfDu * Color * int Tree
|
|
|
|
/// Test cases for possible ambiguity between option types and other DU or records with a 'Some' field.
|
|
module SomeAmbiguity =
|
|
type 'a RecordWithFieldNamedSome = { Some : 'a }
|
|
type DUWithFieldlessCaseNamedSome = Some of string | Bla
|
|
type DUWithCaseWithFieldNamedSome = Some | Bla
|
|
type 'a Ambiguous1 = 'a RecordWithFieldNamedSome option
|
|
type Ambiguous2 = DUWithFieldlessCaseNamedSome option
|
|
type Ambiguous3 = DUWithCaseWithFieldNamedSome option
|
|
|
|
let inline defaultSerialize< ^T> (x: ^T) = Compact.serialize< ^T> x
|
|
|
|
let inline reciprocal< ^T when ^T:equality> (serialize: ^T->string) (deserialize: string-> ^T) (x: ^T) =
|
|
// theoretically one round trip is sufficient; we perform
|
|
// two round trips here to test for possible side-effects
|
|
x |> serialize |> deserialize |> serialize |> deserialize = x
|
|
|
|
let inline canBeSerialized< ^T when ^T:equality> (serialize: ^T->string) (deserialize: string-> ^T) (x: ^T) =
|
|
serialize x |> printfn "%A"
|
|
|
|
let inline areReciprocal< ^T when ^T:equality> (serialize: ^T->string) (deserialize: string-> ^T) (x: ^T) =
|
|
let s = x |> serialize
|
|
let sds = s |> deserialize |> serialize
|
|
Assert.AreEqual(s, sds, sprintf "Inconsistent serialization: 1st call: <%s> 2nd call <%s>. Type %A" s sds (typeof< ^T>))
|
|
let sdsd = sds |> deserialize
|
|
Assert.AreEqual(sdsd, x, sprintf "Did not get the same object back: <%A> gave back <%A> for type %A" x sdsd (typeof< ^T>))
|
|
|
|
/// Check that given object serializes to the specified Json string (using default serializer)
|
|
let inline serializedAs json o =
|
|
let s = defaultSerialize o
|
|
Assert.AreEqual(json, s, sprintf "Object was not serialized to the expected format")
|
|
|
|
/// Check that deserialization coincides with NewtonSoft's default serializer.
|
|
/// That is: when the Json is deserializable by both deserializers Union and Default
|
|
/// they produce the same output object.
|
|
let inline coincidesWithDefault< ^T when ^T:equality> (x: ^T) =
|
|
let deserializationMustCoincide json =
|
|
match Default.tryDeserialize< ^T> json, Compact.tryDeserialize< ^T> json with
|
|
| Choice2Of2 error1, Choice2Of2 error2->
|
|
Assert.IsTrue(true, "Json not parseable by either deserializer: no ambiguity")
|
|
| Choice1Of2 _, Choice2Of2 error
|
|
| Choice2Of2 error, Choice1Of2 _ ->
|
|
Assert.IsTrue(true, "Json parseable by exactly one deserializer: no ambiguity")
|
|
| Choice1Of2 v1, Choice1Of2 v2 when v1 <> v2 ->
|
|
Assert.Fail(sprintf "Deserializers do not coincide: %A <> %A" v1 v2)
|
|
| Choice1Of2 v1, Choice1Of2 v2 ->
|
|
Assert.IsTrue(true)
|
|
x |> Default.serialize |> deserializationMustCoincide
|
|
x |> Compact.serialize |> deserializationMustCoincide
|
|
|
|
/// Check that output format of Default Json.Net serializer can be parsed by
|
|
/// the BackwardCompatible deserializer
|
|
let inline backwardCompatibleWithDefault< ^T when ^T:equality> (x: ^T) =
|
|
let json = x |> Default.serialize
|
|
let o1 = json |> Default.deserialize : ^T
|
|
let o2 = json |> BackwardCompatible.deserialize : ^T
|
|
Assert.AreEqual(o1, o2,
|
|
sprintf "BackwardCompatible should coincide with Json.Net when deserializing default Json format. %A <> %A" o1 o2)
|
|
|
|
type ReciprocalityCompact () =
|
|
static member x1 = reciprocal<ComplexDu> Compact.serialize Compact.deserialize
|
|
static member x2 = reciprocal<ComplexDu RecursiveList> Compact.serialize Compact.deserialize
|
|
static member x3 = reciprocal<WithFields> Compact.serialize Compact.deserialize
|
|
static member x4 = reciprocal<SimpleDu> Compact.serialize Compact.deserialize
|
|
static member x5 = reciprocal<ComplexDu> Compact.serialize Compact.deserialize
|
|
static member x6 = reciprocal<OptionOfBase> Compact.serialize Compact.deserialize
|
|
static member x7 = reciprocal<OptionOfDu> Compact.serialize Compact.deserialize
|
|
static member x8 = reciprocal<Color> Compact.serialize Compact.deserialize
|
|
static member x9 = reciprocal<Shape> Compact.serialize Compact.deserialize
|
|
static member x10 = reciprocal<int Tree> Compact.serialize Compact.deserialize
|
|
static member x11 = reciprocal<int Tree Test> Compact.serialize Compact.deserialize
|
|
static member x12 = reciprocal<int Test> Compact.serialize Compact.deserialize
|
|
static member x13 = reciprocal<int list Tree> Compact.serialize Compact.deserialize
|
|
static member x14 = reciprocal<string NestedOptions> Compact.serialize Compact.deserialize
|
|
static member x15 = reciprocal<string> Compact.serialize Compact.deserialize
|
|
static member x16 = reciprocal<string option> Compact.serialize Compact.deserialize
|
|
static member x17 = reciprocal<string option option> Compact.serialize Compact.deserialize
|
|
static member x18 = reciprocal<string option option option option> Compact.serialize Compact.deserialize
|
|
static member x19 = reciprocal<int NestedOptions> Compact.serialize Compact.deserialize
|
|
static member x20 = reciprocal<SomeAmbiguity.Ambiguous1<string>> Compact.serialize Compact.deserialize
|
|
static member x21 = reciprocal<SomeAmbiguity.Ambiguous1<SimpleDu>> Compact.serialize Compact.deserialize
|
|
static member x22 = reciprocal<NestedOptionStructure> Compact.serialize Compact.deserialize
|
|
static member x23 = reciprocal<SomeAmbiguity.Ambiguous2> Compact.serialize Compact.deserialize
|
|
static member x24 = reciprocal<SomeAmbiguity.Ambiguous3> Compact.serialize Compact.deserialize
|
|
static member x25 = reciprocal<int list> Compact.serialize Compact.deserialize
|
|
static member x26 = reciprocal<SomeTupleType> Compact.serialize Compact.deserialize
|
|
|
|
type ReciprocalityCamelCase () =
|
|
static member x1 = reciprocal<ComplexDu> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x2 = reciprocal<ComplexDu RecursiveList> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x3 = reciprocal<WithFields> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x4 = reciprocal<SimpleDu> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x5 = reciprocal<ComplexDu> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x6 = reciprocal<OptionOfBase> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x7 = reciprocal<OptionOfDu> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x8 = reciprocal<Color> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x9 = reciprocal<Shape> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x10 = reciprocal<int Tree> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x11 = reciprocal<int Tree Test> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x12 = reciprocal<int Test> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x13 = reciprocal<int list Tree> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x14 = reciprocal<string NestedOptions> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x15 = reciprocal<string> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x16 = reciprocal<string option> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x17 = reciprocal<string option option> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x18 = reciprocal<string option option option option> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x19 = reciprocal<int NestedOptions> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x20 = reciprocal<SomeAmbiguity.Ambiguous1<string>> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x21 = reciprocal<SomeAmbiguity.Ambiguous1<SimpleDu>> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x22 = reciprocal<NestedOptionStructure> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x23 = reciprocal<SomeAmbiguity.Ambiguous2> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x24 = reciprocal<SomeAmbiguity.Ambiguous3> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x25 = reciprocal<int list> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
static member x26 = reciprocal<SomeTupleType> CamelCaseSerializer.serialize CamelCaseSerializer.deserialize
|
|
|
|
type CoincidesWithJsonNetOnDeserialization () =
|
|
static member x1 = coincidesWithDefault<ComplexDu>
|
|
static member x2 = coincidesWithDefault<ComplexDu RecursiveList>
|
|
static member x3 = coincidesWithDefault<WithFields>
|
|
static member x4 = coincidesWithDefault<SimpleDu>
|
|
static member x5 = coincidesWithDefault<ComplexDu>
|
|
static member x6 = coincidesWithDefault<OptionOfBase>
|
|
static member x7 = coincidesWithDefault<OptionOfDu>
|
|
static member x8 = coincidesWithDefault<Color>
|
|
static member x9 = coincidesWithDefault<Shape>
|
|
static member x10 = coincidesWithDefault<int Tree>
|
|
static member x11 = coincidesWithDefault<int Tree Test>
|
|
static member x12 = coincidesWithDefault<int Test>
|
|
static member x13 = coincidesWithDefault<int list Tree>
|
|
static member x14 = coincidesWithDefault<string NestedOptions>
|
|
static member x15 = coincidesWithDefault<string>
|
|
static member x16 = coincidesWithDefault<string option>
|
|
static member x17 = coincidesWithDefault<string option option>
|
|
static member x18 = coincidesWithDefault<string option option option option>
|
|
static member x19 = coincidesWithDefault<int NestedOptions>
|
|
static member x20 = coincidesWithDefault<SomeAmbiguity.Ambiguous1<string>>
|
|
static member x21 = coincidesWithDefault<SomeAmbiguity.Ambiguous1<SimpleDu>>
|
|
static member x22 = coincidesWithDefault<NestedOptionStructure>
|
|
static member x23 = coincidesWithDefault<SomeAmbiguity.Ambiguous2>
|
|
static member x24 = coincidesWithDefault<SomeAmbiguity.Ambiguous3>
|
|
static member x25 = coincidesWithDefault<int list>
|
|
static member x26 = coincidesWithDefault<SomeTupleType>
|
|
|
|
|
|
type BackwardCompatibility () =
|
|
static member x1 = backwardCompatibleWithDefault<ComplexDu>
|
|
static member x2 = backwardCompatibleWithDefault<ComplexDu RecursiveList>
|
|
static member x3 = backwardCompatibleWithDefault<WithFields>
|
|
static member x4 = backwardCompatibleWithDefault<SimpleDu>
|
|
static member x5 = backwardCompatibleWithDefault<ComplexDu>
|
|
static member x6 = backwardCompatibleWithDefault<OptionOfBase>
|
|
static member x7 = backwardCompatibleWithDefault<OptionOfDu>
|
|
static member x8 = backwardCompatibleWithDefault<Color>
|
|
static member x9 = backwardCompatibleWithDefault<Shape>
|
|
static member x10 = backwardCompatibleWithDefault<int Tree>
|
|
static member x11 = backwardCompatibleWithDefault<int Tree Test>
|
|
static member x12 = backwardCompatibleWithDefault<int Test>
|
|
static member x13 = backwardCompatibleWithDefault<int list Tree>
|
|
static member x14 = backwardCompatibleWithDefault<string NestedOptions>
|
|
static member x15 = backwardCompatibleWithDefault<string>
|
|
static member x16 = backwardCompatibleWithDefault<string option>
|
|
static member x17 = backwardCompatibleWithDefault<string option option>
|
|
static member x18 = backwardCompatibleWithDefault<string option option option option>
|
|
static member x19 = backwardCompatibleWithDefault<int NestedOptions>
|
|
static member x20 = backwardCompatibleWithDefault<SomeAmbiguity.Ambiguous1<string>>
|
|
static member x21 = backwardCompatibleWithDefault<SomeAmbiguity.Ambiguous1<SimpleDu>>
|
|
static member x22 = backwardCompatibleWithDefault<NestedOptionStructure>
|
|
static member x23 = backwardCompatibleWithDefault<SomeAmbiguity.Ambiguous2>
|
|
static member x24 = backwardCompatibleWithDefault<SomeAmbiguity.Ambiguous3>
|
|
static member x25 = backwardCompatibleWithDefault<int list>
|
|
static member x26 = backwardCompatibleWithDefault<SomeTupleType>
|
|
|
|
|
|
let inline ``Run using all serializers``< ^T when ^T:equality> (test: (^T->string)->(string-> ^T)-> ^T->unit) (input: ^T) =
|
|
[
|
|
Compact.serialize, Compact.deserialize
|
|
Default.serialize, Default.deserialize
|
|
CamelCaseSerializer.serialize, CamelCaseSerializer.deserialize
|
|
BackwardCompatible.serialize, BackwardCompatible.deserialize
|
|
] |> List.iter (fun (s, d) -> test s d input)
|
|
|
|
let inline testBackwardCompat< ^T when ^T:equality> (x: ^T) =
|
|
let y =
|
|
x
|
|
|> Compact.Legacy.serialize< ^T>
|
|
|> Compact.deserialize< ^T>
|
|
|
|
Assert.AreEqual(x, y, "Tuple deserialization is not backward compatible!")
|
|
|
|
type ARecord = {
|
|
id: System.Guid
|
|
name: string
|
|
}
|
|
|
|
let inline assertStrictFailsToDeserialize< ^T> t =
|
|
let s = Compact.Strict.tryDeserialize t
|
|
match s with
|
|
| Choice1Of2 _ -> Assert.IsTrue(true)
|
|
| Choice2Of2 _ -> Assert.IsTrue(false)
|
|
|
|
/// Test for the compact serializer
|
|
[<TestClass>]
|
|
type JsonSerializerTests() =
|
|
|
|
[<ClassInitialize>]
|
|
static member Init(context : TestContext) = ()
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``Serialize field-less DU`` () =
|
|
FooBar |> serializedAs "\"FooBar\""
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``Dont' touch Fsharp lists`` () =
|
|
[1;2;3] |> serializedAs (Default.serialize [1;2;3])
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``Handles Some`` () =
|
|
Some "test" |> serializedAs "\"test\""
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu..Json")>]
|
|
member __.``Handles None`` () =
|
|
None |> serializedAs "null"
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``Handles just the expected types``() =
|
|
let conv = CompactUnionJsonConverter(true)
|
|
Assert.IsTrue(conv.CanConvert(Color.Red.GetType()))
|
|
Assert.IsTrue(conv.CanConvert(typeof<Color>))
|
|
Assert.IsTrue(conv.CanConvert(typeof<_ option>))
|
|
Assert.IsTrue(conv.CanConvert(typeof<_ Tree>))
|
|
Assert.IsTrue(conv.CanConvert(typeof<Shape>))
|
|
Assert.IsFalse(conv.CanConvert(typeof<_ list>))
|
|
Assert.IsFalse(conv.CanConvert(typeof<Map<_,_>>))
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``Serialization does not raise exceptions for basic types``() =
|
|
``Run using all serializers`` canBeSerialized <| Red
|
|
``Run using all serializers`` canBeSerialized <| Blue
|
|
``Run using all serializers`` canBeSerialized <| Circle (8,99)
|
|
``Run using all serializers`` canBeSerialized <| Some 8
|
|
``Run using all serializers`` canBeSerialized <| Some (Circle(5,120))
|
|
``Run using all serializers`` canBeSerialized <| None
|
|
``Run using all serializers`` canBeSerialized <| Some (Node(Leaf 1,Leaf 9))
|
|
``Run using all serializers`` canBeSerialized <| Case1
|
|
``Run using all serializers`` canBeSerialized <| Case2 (3)
|
|
``Run using all serializers`` canBeSerialized <| Case3 (3,"s", "Foo")
|
|
``Run using all serializers`` canBeSerialized <| Circle (8,10)
|
|
``Run using all serializers`` canBeSerialized <| Leaf ["s";"s"]
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``Serialization and deserialization are reciprocal``() =
|
|
``Run using all serializers`` areReciprocal <| Some 8
|
|
``Run using all serializers`` areReciprocal <| Leaf "s"
|
|
``Run using all serializers`` areReciprocal <| Leaf ["s";"s"]
|
|
``Run using all serializers`` areReciprocal <| Leaf "s"
|
|
``Run using all serializers`` areReciprocal <| Some 8
|
|
``Run using all serializers`` areReciprocal <| Red
|
|
``Run using all serializers`` areReciprocal <| Circle (8,10)
|
|
``Run using all serializers`` areReciprocal <| Node((Leaf "s"),(Leaf "s"))
|
|
``Run using all serializers`` areReciprocal <| Leaf ["s";"s"]
|
|
``Run using all serializers`` areReciprocal <| Node((Leaf 1),(Leaf 9))
|
|
``Run using all serializers`` areReciprocal <| Case1
|
|
``Run using all serializers`` areReciprocal <| Case2 (3)
|
|
``Run using all serializers`` areReciprocal <| Case3 (3,"s", "Foo")
|
|
``Run using all serializers`` areReciprocal <| (["test", [3;3;4]] |> Map.ofSeq)
|
|
``Run using all serializers`` areReciprocal <| ["test", [3;3;4]]
|
|
``Run using all serializers`` areReciprocal <| Some (Some (Some None))
|
|
``Run using all serializers`` areReciprocal <| Some (Some None)
|
|
``Run using all serializers`` areReciprocal <| Some null
|
|
``Run using all serializers`` areReciprocal <| Some None
|
|
``Run using all serializers`` areReciprocal <| Some (Some (Some None))
|
|
``Run using all serializers`` areReciprocal <| (1,2,3,4,5,6,7,8,9,10)
|
|
``Run using all serializers`` areReciprocal <| [ "UnDromadaire", 1; "UnChameau", 2; "DeuxChats", 3 ]
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json")>]
|
|
member __.``No ambiguity between records and Option type``() =
|
|
``Run using all serializers`` areReciprocal <| Some (Some (Some None))
|
|
``Run using all serializers`` areReciprocal <| { SomeAmbiguity.Some = null }
|
|
``Run using all serializers`` areReciprocal <| { SomeAmbiguity.Some = SimpleDu.Foo }
|
|
``Run using all serializers`` areReciprocal <| { SomeAmbiguity.Some = "test" }
|
|
``Run using all serializers`` areReciprocal <| { SomeAmbiguity.Some = 123 }
|
|
``Run using all serializers`` areReciprocal <| (Option.Some { SomeAmbiguity.Some = 345 })
|
|
``Run using all serializers`` areReciprocal <| (Option.Some <| SomeAmbiguity.DUWithFieldlessCaseNamedSome.Some "ambiguous")
|
|
``Run using all serializers`` areReciprocal <| (Option.Some { SomeAmbiguity.RecordWithFieldNamedSome.Some = 8 })
|
|
``Run using all serializers`` areReciprocal <| (Option.Some <| SomeAmbiguity.DUWithCaseWithFieldNamedSome.Some)
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.CamelCase")>]
|
|
member __.``CamelCaseSerializer handles discriminated unions`` () =
|
|
let du = ComplexDu <| SomeField (2, 3)
|
|
let str = CamelCaseSerializer.serialize du
|
|
Assert.AreEqual("""{"complexDu":{"someField":[2,3]}}""", str)
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.CamelCase")>]
|
|
member __.``CamelCaseSerializer handles discriminated unions with consecutive uppercase characters`` () =
|
|
let du = [ FOO ; FOOWithRecord { BAR=2; BAZNumber=3 } ]
|
|
let str = CamelCaseSerializer.serialize du
|
|
Assert.AreEqual("""["FOO",{"fooWithRecord":{"bar":2,"bazNumber":3}}]""", str)
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.CamelCase")>]
|
|
member __.``CamelCaseSerializer makes properties camelCase but not values`` () =
|
|
let du = [ AString "foo"; SimpleDU ]
|
|
let str = CamelCaseSerializer.serialize du
|
|
Assert.AreEqual("""[{"aString":"foo"},"SimpleDU"]""", str)
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.CamelCase")>]
|
|
member __.``CamelCaseSerializer handles option type`` () =
|
|
let du = { WrappedField = Some Red }
|
|
let str = CamelCaseSerializer.serialize du
|
|
Assert.AreEqual("""{"wrappedField":"Red"}""", str)
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Fuzzing")>]
|
|
member __.``Fuzzing Reciprocal Compact`` () =
|
|
Check.VerboseThrowOnFailureAll<ReciprocalityCompact>()
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Fuzzing")>]
|
|
member __.``Fuzzing Reciprocal CamelCase`` () =
|
|
Check.VerboseThrowOnFailureAll<ReciprocalityCamelCase>()
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Fuzzing")>]
|
|
member __.``Deserialization coincides with JSon.Net (Fuzzing)`` () =
|
|
Check.VerboseThrowOnFailureAll<CoincidesWithJsonNetOnDeserialization>()
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Fuzzing")>]
|
|
member __.``BackwardCompatible deserializes default Json.Net format and returns same object`` () =
|
|
Check.VerboseThrowOnFailureAll<BackwardCompatibility>()
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Tuples")>]
|
|
member __.``Serialize tuples as list`` () =
|
|
(1, 2) |> serializedAs (defaultSerialize [1; 2])
|
|
(1, 2, 3) |> serializedAs (defaultSerialize [1; 2; 3])
|
|
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |> serializedAs (defaultSerialize [1; 2; 3; 4; 5; 6; 7; 8; 9; 10])
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Tuples")>]
|
|
member __.``Tuple serialization is backward compatible`` () =
|
|
(1, 2) |> testBackwardCompat
|
|
(1, "test", 5) |> testBackwardCompat
|
|
(1, ["foo"; "bar"]) |> testBackwardCompat
|
|
(1, ["foo"; "bar"], 4, "hello", ("bird", 3), 2, 3, 2, 4, 7) |> testBackwardCompat
|
|
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |> testBackwardCompat
|
|
// Check for nested serialization: legacy JSON.net serialization breaks down tuples
|
|
// in buckets of 7 elements maximum. Each additional bucket gets nested under a
|
|
// "Rest" JSON field.
|
|
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17) |> testBackwardCompat
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Tuples")>]
|
|
member __.``Legacy tuple deserialization handles property reordering`` () =
|
|
let r =
|
|
"""{ "Item3": 3, "Item2": 2, "Item1": 1 }"""
|
|
|> Compact.deserialize<int*int*int>
|
|
Assert.AreEqual(r, (1,2,3), "Tuple deserialization should handle JSON properties in any order")
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Strictness")>]
|
|
member __.``Reject missing fields`` () =
|
|
assertStrictFailsToDeserialize<ARecord> """{ "name":"hola" }"""
|
|
assertStrictFailsToDeserialize<ARecord> """{ "id":"f893e695-496d-4e30-8fc7-b2ff59725e6c" }"""
|
|
Assert.ThrowsException<JsonSerializationException>(fun () -> Compact.Strict.deserialize<ARecord> """{ "name":"hola" }""" |> ignore) |> ignore
|
|
()
|
|
|
|
[<TestMethod>]
|
|
[<TestCategory("FSharpLu.Json.Dictionary")>]
|
|
member __.``Don't change the casing of dictionary keys`` () =
|
|
let d = [ "UnDromadaire", 1
|
|
"UnChameau", 2
|
|
"DeuxChats", 3 ] |> dict
|
|
|
|
let camel = CamelCaseSerializer.serialize d
|
|
Assert.AreEqual("""{"UnDromadaire":1,"UnChameau":2,"DeuxChats":3}""", camel)
|
|
|
|
let compact = Compact.serialize d
|
|
Assert.AreEqual("""{
|
|
"UnDromadaire": 1,
|
|
"UnChameau": 2,
|
|
"DeuxChats": 3
|
|
}""", compact)
|