mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-05 03:58:40 +00:00
Implement
This commit is contained in:
@@ -5,7 +5,7 @@ open WoofWare.Myriad.Plugins
|
||||
|
||||
[<GenerateCapturingMock>]
|
||||
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> =
|
||||
|
||||
[<GenerateCapturingMock>]
|
||||
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
|
||||
|
@@ -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<Mem1Call<'a>>
|
||||
Mem1_Calls : ResizeArray<CurriedMockCalls.Mem1Call<'a>>
|
||||
Mem2 : int * string -> 'a -> string
|
||||
Mem2_Calls : ResizeArray<Mem2Call<'a>>
|
||||
Mem2_Calls : ResizeArray<CurriedMockCalls.Mem2Call<'a>>
|
||||
Mem3 : (int * string) -> 'a -> string
|
||||
Mem3_Calls : ResizeArray<Mem3Call<'a>>
|
||||
Mem3_Calls : ResizeArray<CurriedMockCalls.Mem3Call<'a>>
|
||||
Mem4 : (int * string) -> ('a * int) -> string
|
||||
Mem4_Calls : ResizeArray<Mem4Call<'a>>
|
||||
Mem4_Calls : ResizeArray<CurriedMockCalls.Mem4Call<'a>>
|
||||
Mem5 : int * string -> ('a * int) -> string
|
||||
Mem5_Calls : ResizeArray<Mem5Call<'a>>
|
||||
Mem5_Calls : ResizeArray<CurriedMockCalls.Mem5Call<'a>>
|
||||
Mem6 : int * string -> 'a * int -> string
|
||||
Mem6_Calls : ResizeArray<Mem6Call<'a>>
|
||||
Mem6_Calls : ResizeArray<CurriedMockCalls.Mem6Call<'a>>
|
||||
}
|
||||
|
||||
/// 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)
|
||||
|
@@ -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<Mem1Call<'a>>
|
||||
Mem1_Calls : ResizeArray<CurriedNoAttrMockCalls.Mem1Call<'a>>
|
||||
Mem2 : int * string -> 'a -> string
|
||||
Mem2_Calls : ResizeArray<Mem2Call<'a>>
|
||||
Mem2_Calls : ResizeArray<CurriedNoAttrMockCalls.Mem2Call<'a>>
|
||||
Mem3 : (int * string) -> 'a -> string
|
||||
Mem3_Calls : ResizeArray<Mem3Call<'a>>
|
||||
Mem3_Calls : ResizeArray<CurriedNoAttrMockCalls.Mem3Call<'a>>
|
||||
Mem4 : (int * string) -> ('a * int) -> string
|
||||
Mem4_Calls : ResizeArray<Mem4Call<'a>>
|
||||
Mem4_Calls : ResizeArray<CurriedNoAttrMockCalls.Mem4Call<'a>>
|
||||
Mem5 : int * string -> ('a * int) -> string
|
||||
Mem5_Calls : ResizeArray<Mem5Call<'a>>
|
||||
Mem5_Calls : ResizeArray<CurriedNoAttrMockCalls.Mem5Call<'a>>
|
||||
Mem6 : int * string -> 'a * int -> string
|
||||
Mem6_Calls : ResizeArray<Mem6Call<'a>>
|
||||
Mem6_Calls : ResizeArray<CurriedNoAttrMockCalls.Mem6Call<'a>>
|
||||
}
|
||||
|
||||
/// An implementation where every non-unit method throws.
|
||||
|
@@ -6,7 +6,7 @@ open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestMockGenerator =
|
||||
module TestCapturingMockGenerator =
|
||||
|
||||
[<Test>]
|
||||
let ``Example of use: IPublicType`` () =
|
||||
|
@@ -6,7 +6,7 @@ open NUnit.Framework
|
||||
open FsUnitTyped
|
||||
|
||||
[<TestFixture>]
|
||||
module TestCapturingMockGeneratorNoAttr =
|
||||
module TestMockGeneratorNoAttr =
|
||||
|
||||
[<Test>]
|
||||
let ``Example of use: IPublicType`` () =
|
@@ -28,7 +28,9 @@
|
||||
<Compile Include="TestHttpClient\TestVaultClient.fs" />
|
||||
<Compile Include="TestHttpClient\TestVariableHeader.fs" />
|
||||
<Compile Include="TestMockGenerator\TestMockGenerator.fs" />
|
||||
<Compile Include="TestMockGenerator\TestCapturingMockGeneratorNoAttr.fs" />
|
||||
<Compile Include="TestMockGenerator\TestMockGeneratorNoAttr.fs" />
|
||||
<Compile Include="TestCapturingMockGenerator\TestCapturingMockGenerator.fs" />
|
||||
<Compile Include="TestCapturingMockGenerator\TestCapturingMockGeneratorNoAttr.fs" />
|
||||
<Compile Include="TestJsonSerialize\TestJsonSerde.fs" />
|
||||
<Compile Include="TestCataGenerator\TestCataGenerator.fs" />
|
||||
<Compile Include="TestCataGenerator\TestDirectory.fs" />
|
||||
@@ -67,9 +69,4 @@
|
||||
<ProjectReference Include="..\ConsumePlugin\ConsumePlugin.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="TestCapturingMockGenerator\TestCapturingMockGenerator.fs" />
|
||||
<Compile Include="TestCapturingMockGenerator\TestCapturingMockGeneratorNoAttr.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "8.0",
|
||||
"version": "8.1",
|
||||
"publicReleaseRefSpec": [
|
||||
"^refs/heads/main$"
|
||||
],
|
||||
|
Reference in New Issue
Block a user