Created
February 26, 2019 17:18
-
-
Save Szer/eb034950b4c70146aef7f21328c8b30e to your computer and use it in GitHub Desktop.
Generate type serialization tests because I'm lazy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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