Skip to content

Instantly share code, notes, and snippets.

@Szer
Created February 26, 2019 17:18
Show Gist options
  • Save Szer/eb034950b4c70146aef7f21328c8b30e to your computer and use it in GitHub Desktop.
Save Szer/eb034950b4c70146aef7f21328c8b30e to your computer and use it in GitHub Desktop.
Generate type serialization tests because I'm lazy
#r @"C:\Users\ayrat.hudaygulov\.nuget\packages\fsharp.compiler.service\26.0.1\lib\net45\FSharp.Compiler.Service.dll"
open System.IO
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.SourceCodeServices
let parse text =
let fileName = "whatever.fs"
let checker = FSharpChecker.Create()
let opts =
{ FSharpParsingOptions.Default with
SourceFiles = [|fileName|] }
let res = checker.ParseFile(fileName, text, opts) |> Async.RunSynchronously
let fileAst =
match res.ParseTree.Value with
| ParsedInput.ImplFile x -> x
| ParsedInput.SigFile _ -> failwith "give me fs, not fsi"
let (ParsedImplFileInput.ParsedImplFileInput(_, _, _, _, _, modules, _)) = fileAst
let (SynModuleOrNamespace.SynModuleOrNamespace(_, _, _, moduleDeclarations, _, _, _, _)) = modules.[0]
moduleDeclarations
let code = File.ReadAllText @"C:\dev\superman\FSharp\Superman.Domain\Types.fs"
let ast = parse code |> List.head
let (SynModuleDecl.NestedModule (_,_,decls,_,_)) = ast
let types =
decls
|> List.filter (function
| SynModuleDecl.Types _ -> true
| _ -> false)
|> List.collect (fun (SynModuleDecl.Types (x,_)) -> x)
let (|MemberName|_|) name (SynMemberDefn.Member (mmbrDef,_)) =
let (SynBinding.Binding (_,_,_,_,_,_,_,pat,_,_,_,_)) = mmbrDef
match pat with
| (SynPat.LongIdent (LongIdentWithDots ([id],_),_,_,_,_,_)) ->
if id.idText = name then Some MemberName else None
| _ -> None
let (|IsStatic|_|) (SynMemberDefn.Member (mmbrDef,_)) =
let (SynBinding.Binding (_,_,_,_,_,_,valData,_,_,_,_,_)) = mmbrDef
let (SynValData.SynValData (flags,_,_)) = valData
if flags.IsSome then
if flags.Value.IsInstance then None else Some IsStatic
else
None
let (|Type|) (SynTypeDefn.TypeDefn (info,_,members,_)) =
let (SynComponentInfo.ComponentInfo (_,_,_,[ident],_,_,_,_)) = info
Type (ident.idText, members)
let validTypes =
types
|> List.choose (fun ((Type (name, members)) as t) ->
let bothMethodExists =
members
|> List.filter (function
| IsStatic & MemberName "FromJson"
| IsStatic & MemberName "ToJson" -> true
| _ -> false)
|> List.length
|> fun l -> l = 2
if bothMethodExists then Some name else None)
let generateTest typeName =
sprintf
"""
[<Property>]
member __.``%s serialization should return same object`` (input: %s) = test input
""" typeName typeName
let methods =
validTypes
|> Seq.map generateTest
|> String.concat ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment