-
-
Save medigor/0d36ef9fe9136d631425e4d83a152d32 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