diff --git a/ConsumePlugin/CapturingMockExample.fs b/ConsumePlugin/CapturingMockExample.fs index 9ed23b3..7fd8260 100644 --- a/ConsumePlugin/CapturingMockExample.fs +++ b/ConsumePlugin/CapturingMockExample.fs @@ -5,7 +5,7 @@ open WoofWare.Myriad.Plugins [] type IPublicType = - abstract Mem1 : string * int -> string list + abstract Mem1 : foo : string * int -> string list abstract Mem2 : string -> int abstract Mem3 : x : int * ?ct : System.Threading.CancellationToken -> string @@ -36,9 +36,9 @@ type VeryPublicType<'a, 'b> = [] type Curried<'a> = - abstract Mem1 : int -> 'a -> string - abstract Mem2 : int * string -> 'a -> string - abstract Mem3 : (int * string) -> 'a -> string + abstract Mem1 : bar : int -> 'a -> string + abstract Mem2 : int * string -> baz : 'a -> string + abstract Mem3 : quux : (int * string) -> flurb : 'a -> string abstract Mem4 : (int * string) -> ('a * int) -> string abstract Mem5 : x : int * string -> ('a * int) -> string abstract Mem6 : int * string -> y : 'a * int -> string diff --git a/ConsumePlugin/GeneratedCapturingMock.fs b/ConsumePlugin/GeneratedCapturingMock.fs index 0585d38..040e2c7 100644 --- a/ConsumePlugin/GeneratedCapturingMock.fs +++ b/ConsumePlugin/GeneratedCapturingMock.fs @@ -170,63 +170,64 @@ namespace SomeNamespace.CapturingMock open System open WoofWare.Myriad.Plugins -/// A single call to the Mem1 method -type internal Mem1Call<'a> = - { - arg0 : int - arg1 : 'a - } +module internal CurriedMockCalls = + /// A single call to the Mem1 method + type internal Mem1Call<'a> = + { + bar : int + Arg1 : 'a + } -/// A single call to the Mem2 method -type internal Mem2Call<'a> = - { - arg0 : int * string - arg1 : 'a - } + /// A single call to the Mem2 method + type internal Mem2Call<'a> = + { + Arg0 : int * string + baz : 'a + } -/// A single call to the Mem3 method -type internal Mem3Call<'a> = - { - arg0 : int * string - arg1 : 'a - } + /// A single call to the Mem3 method + type internal Mem3Call<'a> = + { + quux : (int * string) + flurb : 'a + } -/// A single call to the Mem4 method -type internal Mem4Call<'a> = - { - arg0 : int * string - arg1 : 'a * int - } + /// A single call to the Mem4 method + type internal Mem4Call<'a> = + { + Arg0 : int * string + Arg1 : 'a * int + } -/// A single call to the Mem5 method -type internal Mem5Call<'a> = - { - arg0 : int * string - arg1 : 'a * int - } + /// A single call to the Mem5 method + type internal Mem5Call<'a> = + { + Arg0 : int * string + Arg1 : 'a * int + } -/// A single call to the Mem6 method -type internal Mem6Call<'a> = - { - arg0 : int * string - arg1 : 'a * int - } + /// A single call to the Mem6 method + type internal Mem6Call<'a> = + { + Arg0 : int * string + Arg1 : 'a * int + } /// Mock record type for an interface type internal CurriedMock<'a> = { Mem1 : int -> 'a -> string - Mem1_Calls : ResizeArray> + Mem1_Calls : ResizeArray> Mem2 : int * string -> 'a -> string - Mem2_Calls : ResizeArray> + Mem2_Calls : ResizeArray> Mem3 : (int * string) -> 'a -> string - Mem3_Calls : ResizeArray> + Mem3_Calls : ResizeArray> Mem4 : (int * string) -> ('a * int) -> string - Mem4_Calls : ResizeArray> + Mem4_Calls : ResizeArray> Mem5 : int * string -> ('a * int) -> string - Mem5_Calls : ResizeArray> + Mem5_Calls : ResizeArray> Mem6 : int * string -> 'a * int -> string - Mem6_Calls : ResizeArray> + Mem6_Calls : ResizeArray> } /// An implementation where every non-unit method throws. @@ -249,7 +250,7 @@ type internal CurriedMock<'a> = interface Curried<'a> with member this.Mem1 arg_0_0 arg_1_0 = this.Mem1 (arg_0_0) (arg_1_0) member this.Mem2 (arg_0_0, arg_0_1) arg_1_0 = this.Mem2 (arg_0_0, arg_0_1) (arg_1_0) - member this.Mem3 ((arg_0_0, arg_0_1)) arg_1_0 = this.Mem3 (arg_0_0, arg_0_1) (arg_1_0) + member this.Mem3 arg_0_0 arg_1_0 = this.Mem3 (arg_0_0) (arg_1_0) member this.Mem4 ((arg_0_0, arg_0_1)) ((arg_1_0, arg_1_1)) = this.Mem4 (arg_0_0, arg_0_1) (arg_1_0, arg_1_1) diff --git a/ConsumePlugin/GeneratedCapturingMockNoAttributes.fs b/ConsumePlugin/GeneratedCapturingMockNoAttributes.fs index 7b1d747..8a42aa8 100644 --- a/ConsumePlugin/GeneratedCapturingMockNoAttributes.fs +++ b/ConsumePlugin/GeneratedCapturingMockNoAttributes.fs @@ -163,63 +163,64 @@ namespace SomeNamespace.CapturingMock open System -/// A single call to the Mem1 method -type internal Mem1Call<'a> = - { - arg0 : int - arg1 : 'a - } +module internal CurriedNoAttrMockCalls = + /// A single call to the Mem1 method + type internal Mem1Call<'a> = + { + Arg0 : int + Arg1 : 'a + } -/// A single call to the Mem2 method -type internal Mem2Call<'a> = - { - arg0 : int * string - arg1 : 'a - } + /// A single call to the Mem2 method + type internal Mem2Call<'a> = + { + Arg0 : int * string + Arg1 : 'a + } -/// A single call to the Mem3 method -type internal Mem3Call<'a> = - { - arg0 : int * string - arg1 : 'a - } + /// A single call to the Mem3 method + type internal Mem3Call<'a> = + { + Arg0 : int * string + Arg1 : 'a + } -/// A single call to the Mem4 method -type internal Mem4Call<'a> = - { - arg0 : int * string - arg1 : 'a * int - } + /// A single call to the Mem4 method + type internal Mem4Call<'a> = + { + Arg0 : int * string + Arg1 : 'a * int + } -/// A single call to the Mem5 method -type internal Mem5Call<'a> = - { - arg0 : int * string - arg1 : 'a * int - } + /// A single call to the Mem5 method + type internal Mem5Call<'a> = + { + Arg0 : int * string + Arg1 : 'a * int + } -/// A single call to the Mem6 method -type internal Mem6Call<'a> = - { - arg0 : int * string - arg1 : 'a * int - } + /// A single call to the Mem6 method + type internal Mem6Call<'a> = + { + Arg0 : int * string + Arg1 : 'a * int + } /// Mock record type for an interface type internal CurriedNoAttrMock<'a> = { Mem1 : int -> 'a -> string - Mem1_Calls : ResizeArray> + Mem1_Calls : ResizeArray> Mem2 : int * string -> 'a -> string - Mem2_Calls : ResizeArray> + Mem2_Calls : ResizeArray> Mem3 : (int * string) -> 'a -> string - Mem3_Calls : ResizeArray> + Mem3_Calls : ResizeArray> Mem4 : (int * string) -> ('a * int) -> string - Mem4_Calls : ResizeArray> + Mem4_Calls : ResizeArray> Mem5 : int * string -> ('a * int) -> string - Mem5_Calls : ResizeArray> + Mem5_Calls : ResizeArray> Mem6 : int * string -> 'a * int -> string - Mem6_Calls : ResizeArray> + Mem6_Calls : ResizeArray> } /// An implementation where every non-unit method throws. diff --git a/WoofWare.Myriad.Plugins.Test/TestCapturingMockGenerator/TestCapturingMockGenerator.fs b/WoofWare.Myriad.Plugins.Test/TestCapturingMockGenerator/TestCapturingMockGenerator.fs index b2afb29..3b19834 100644 --- a/WoofWare.Myriad.Plugins.Test/TestCapturingMockGenerator/TestCapturingMockGenerator.fs +++ b/WoofWare.Myriad.Plugins.Test/TestCapturingMockGenerator/TestCapturingMockGenerator.fs @@ -6,7 +6,7 @@ open NUnit.Framework open FsUnitTyped [] -module TestMockGenerator = +module TestCapturingMockGenerator = [] let ``Example of use: IPublicType`` () = diff --git a/WoofWare.Myriad.Plugins.Test/TestMockGenerator/TestCapturingMockGeneratorNoAttr.fs b/WoofWare.Myriad.Plugins.Test/TestMockGenerator/TestMockGeneratorNoAttr.fs similarity index 96% rename from WoofWare.Myriad.Plugins.Test/TestMockGenerator/TestCapturingMockGeneratorNoAttr.fs rename to WoofWare.Myriad.Plugins.Test/TestMockGenerator/TestMockGeneratorNoAttr.fs index 84702af..bff8aba 100644 --- a/WoofWare.Myriad.Plugins.Test/TestMockGenerator/TestCapturingMockGeneratorNoAttr.fs +++ b/WoofWare.Myriad.Plugins.Test/TestMockGenerator/TestMockGeneratorNoAttr.fs @@ -6,7 +6,7 @@ open NUnit.Framework open FsUnitTyped [] -module TestCapturingMockGeneratorNoAttr = +module TestMockGeneratorNoAttr = [] let ``Example of use: IPublicType`` () = diff --git a/WoofWare.Myriad.Plugins.Test/WoofWare.Myriad.Plugins.Test.fsproj b/WoofWare.Myriad.Plugins.Test/WoofWare.Myriad.Plugins.Test.fsproj index 8f1989f..1f6feb7 100644 --- a/WoofWare.Myriad.Plugins.Test/WoofWare.Myriad.Plugins.Test.fsproj +++ b/WoofWare.Myriad.Plugins.Test/WoofWare.Myriad.Plugins.Test.fsproj @@ -28,7 +28,9 @@ - + + + @@ -67,9 +69,4 @@ - - - - - diff --git a/WoofWare.Myriad.Plugins/CapturingInterfaceMockGenerator.fs b/WoofWare.Myriad.Plugins/CapturingInterfaceMockGenerator.fs index 129931d..b148d4d 100644 --- a/WoofWare.Myriad.Plugins/CapturingInterfaceMockGenerator.fs +++ b/WoofWare.Myriad.Plugins/CapturingInterfaceMockGenerator.fs @@ -41,7 +41,12 @@ module internal CapturingInterfaceMockGenerator = args |> List.mapi (fun i tupledArg -> { - SynFieldData.Ident = $"arg%i{i}" |> Ident.create |> Some + SynFieldData.Ident = + match tupledArg.Args with + | [ arg ] -> arg.Id + | _ -> None + |> Option.defaultValue (Ident.create $"Arg%i{i}") + |> Some Attrs = [] Type = tupledArg.Args @@ -115,12 +120,7 @@ module internal CapturingInterfaceMockGenerator = /// Builds the record field for the mock object, and also if applicable a type representing a single call to /// that object (packaging up the args of the call). - let private constructMember - (spec : CapturingInterfaceMockOutputSpec) - (generics : SynTyparDecls option) - (mem : MemberInfo) - : SynField * CallField - = + let private constructMember (spec : CapturingInterfaceMockOutputSpec) (mem : MemberInfo) : SynField * CallField = let inputType = mem.Args |> List.map constructMemberSinglePlace let funcType = SynType.toFun inputType mem.ReturnType @@ -179,11 +179,11 @@ module internal CapturingInterfaceMockGenerator = (name : string) (interfaceType : InterfaceType) (xmlDoc : PreXmlDoc) - : SynModuleDecl + : SynModuleDecl option * SynModuleDecl = let fields = interfaceType.Members - |> List.map (constructMember spec interfaceType.Generics) + |> List.map (constructMember spec) |> List.append ( interfaceType.Properties |> List.map constructProperty @@ -252,15 +252,11 @@ module internal CapturingInterfaceMockGenerator = let callsArrays = fields - |> List.map (fun (_field, extraType, fieldName) -> + |> List.map (fun (_field, _, fieldName) -> let name = SynLongIdent.createS $"{fieldName}_Calls" let init = - match extraType with - | CallField.Original _ -> - SynExpr.createIdent "ResizeArray" |> SynExpr.applyTo (SynExpr.CreateConst ()) - | CallField.ArgsObject _ -> - SynExpr.createIdent "ResizeArray" |> SynExpr.applyTo (SynExpr.CreateConst ()) + SynExpr.createIdent "ResizeArray" |> SynExpr.applyTo (SynExpr.CreateConst ()) name, init ) @@ -305,17 +301,19 @@ module internal CapturingInterfaceMockGenerator = Type = SynType.app "ResizeArray" [ ty ] } |> SynField.make - | CallField.ArgsObject (name, _, generics) -> + | CallField.ArgsObject (argsObjectName, _, generics) -> { Attrs = [] Ident = Some (fieldName + "_Calls" |> Ident.create) Type = match generics with - | None -> SynType.named name.idText + | None -> SynType.named argsObjectName.idText | Some generics -> generics.TyparDecls |> List.map (fun (SynTyparDecl.SynTyparDecl (_, typar)) -> SynType.var typar) - |> SynType.app name.idText + |> SynType.app' ( + SynType.createLongIdent' [ $"%s{name}Calls" ; argsObjectName.idText ] + ) |> List.singleton |> SynType.app "ResizeArray" } @@ -445,16 +443,25 @@ module internal CapturingInterfaceMockGenerator = let typeDecl = AstHelper.defineRecordType record - SynModuleDecl.Types ( - [ - for _, field, _ in fields do - match field with - | CallField.Original _ -> () - | CallField.ArgsObject (_, callType, _) -> yield callType - yield typeDecl - ], - range0 - ) + let callsModule = + fields + |> List.choose (fun (_, field, _) -> + match field with + | CallField.Original _ -> None + | CallField.ArgsObject (_, callType, _) -> Some callType + ) + |> function + | [] -> None + | l -> + SynModuleDecl.Types (l, range0) + |> List.singleton + |> SynModuleDecl.nestedModule ( + SynComponentInfo.create (Ident.create $"%s{name}Calls") + |> SynComponentInfo.withAccessibility access + ) + |> Some + + (callsModule, SynModuleDecl.Types ([ typeDecl ], range0)) let createRecord (namespaceId : LongIdent) @@ -476,9 +483,15 @@ module internal CapturingInterfaceMockGenerator = s |> fun s -> s + "Mock" - let typeDecl = createType spec name interfaceType docString + let callsTypes, typeDecl = createType spec name interfaceType docString - [ yield! opens |> List.map SynModuleDecl.openAny ; yield typeDecl ] + [ + yield! opens |> List.map SynModuleDecl.openAny + match callsTypes with + | None -> () + | Some c -> yield c + yield typeDecl + ] |> SynModuleOrNamespace.createNamespace namespaceId open Myriad.Core diff --git a/WoofWare.Myriad.Plugins/SurfaceBaseline.txt b/WoofWare.Myriad.Plugins/SurfaceBaseline.txt index 71090ea..c8398a2 100644 --- a/WoofWare.Myriad.Plugins/SurfaceBaseline.txt +++ b/WoofWare.Myriad.Plugins/SurfaceBaseline.txt @@ -1,5 +1,7 @@ WoofWare.Myriad.Plugins.ArgParserGenerator inherit obj, implements Myriad.Core.IMyriadGenerator WoofWare.Myriad.Plugins.ArgParserGenerator..ctor [constructor]: unit +WoofWare.Myriad.Plugins.CapturingInterfaceMockGenerator inherit obj, implements Myriad.Core.IMyriadGenerator +WoofWare.Myriad.Plugins.CapturingInterfaceMockGenerator..ctor [constructor]: unit WoofWare.Myriad.Plugins.CreateCatamorphismGenerator inherit obj, implements Myriad.Core.IMyriadGenerator WoofWare.Myriad.Plugins.CreateCatamorphismGenerator..ctor [constructor]: unit WoofWare.Myriad.Plugins.HttpClientGenerator inherit obj, implements Myriad.Core.IMyriadGenerator diff --git a/WoofWare.Myriad.Plugins/version.json b/WoofWare.Myriad.Plugins/version.json index 2b82b63..828acfc 100644 --- a/WoofWare.Myriad.Plugins/version.json +++ b/WoofWare.Myriad.Plugins/version.json @@ -1,5 +1,5 @@ { - "version": "8.0", + "version": "8.1", "publicReleaseRefSpec": [ "^refs/heads/main$" ],