mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-08 13:38:39 +00:00
Allow properties in mocked interfaces (#336)
This commit is contained in:
@@ -206,3 +206,34 @@ type internal TypeWithInterfaceMock =
|
|||||||
|
|
||||||
interface System.IDisposable with
|
interface System.IDisposable with
|
||||||
member this.Dispose () : unit = this.Dispose ()
|
member this.Dispose () : unit = this.Dispose ()
|
||||||
|
namespace SomeNamespace
|
||||||
|
|
||||||
|
open System
|
||||||
|
open WoofWare.Myriad.Plugins
|
||||||
|
|
||||||
|
/// Mock record type for an interface
|
||||||
|
type internal TypeWithPropertiesMock =
|
||||||
|
{
|
||||||
|
/// Implementation of IDisposable.Dispose
|
||||||
|
Dispose : unit -> unit
|
||||||
|
Prop1 : unit -> int
|
||||||
|
Prop2 : unit -> unit Async
|
||||||
|
Mem1 : string option -> string[] Async
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An implementation where every method throws.
|
||||||
|
static member Empty : TypeWithPropertiesMock =
|
||||||
|
{
|
||||||
|
Dispose = (fun () -> ())
|
||||||
|
Prop1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Prop1"))
|
||||||
|
Prop2 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Prop2"))
|
||||||
|
Mem1 = (fun _ -> raise (System.NotImplementedException "Unimplemented mock function: Mem1"))
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TypeWithProperties with
|
||||||
|
member this.Mem1 arg_0_0 = this.Mem1 (arg_0_0)
|
||||||
|
member this.Prop1 = this.Prop1 ()
|
||||||
|
member this.Prop2 = this.Prop2 ()
|
||||||
|
|
||||||
|
interface System.IDisposable with
|
||||||
|
member this.Dispose () : unit = this.Dispose ()
|
||||||
|
@@ -48,3 +48,10 @@ type TypeWithInterface =
|
|||||||
inherit IDisposable
|
inherit IDisposable
|
||||||
abstract Mem1 : string option -> string[] Async
|
abstract Mem1 : string option -> string[] Async
|
||||||
abstract Mem2 : unit -> string[] Async
|
abstract Mem2 : unit -> string[] Async
|
||||||
|
|
||||||
|
[<GenerateMock>]
|
||||||
|
type TypeWithProperties =
|
||||||
|
inherit IDisposable
|
||||||
|
abstract Mem1 : string option -> string[] Async
|
||||||
|
abstract Prop1 : int
|
||||||
|
abstract Prop2 : unit Async
|
||||||
|
@@ -34,3 +34,16 @@ module TestMockGenerator =
|
|||||||
mock.Mem1 3 'a' |> shouldEqual "aaa"
|
mock.Mem1 3 'a' |> shouldEqual "aaa"
|
||||||
mock.Mem2 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
mock.Mem2 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||||
mock.Mem3 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
mock.Mem3 (3, "hi") 'a' |> shouldEqual "hiahiahi"
|
||||||
|
|
||||||
|
[<Test>]
|
||||||
|
let ``Example of use: properties`` () =
|
||||||
|
let mock : TypeWithProperties =
|
||||||
|
{ TypeWithPropertiesMock.Empty with
|
||||||
|
Mem1 = fun i -> async { return Option.toArray i }
|
||||||
|
Prop1 = fun () -> 44
|
||||||
|
}
|
||||||
|
:> _
|
||||||
|
|
||||||
|
mock.Mem1 (Some "hi") |> Async.RunSynchronously |> shouldEqual [| "hi" |]
|
||||||
|
|
||||||
|
mock.Prop1 |> shouldEqual 44
|
||||||
|
@@ -159,6 +159,15 @@ module internal InterfaceMockGenerator =
|
|||||||
|> SynMemberDefn.memberImplementation
|
|> SynMemberDefn.memberImplementation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
let properties =
|
||||||
|
interfaceType.Properties
|
||||||
|
|> List.map (fun pi ->
|
||||||
|
SynExpr.createLongIdent' [ Ident.create "this" ; pi.Identifier ]
|
||||||
|
|> SynExpr.applyTo (SynExpr.CreateConst ())
|
||||||
|
|> SynBinding.basic [ Ident.create "this" ; pi.Identifier ] []
|
||||||
|
|> SynMemberDefn.memberImplementation
|
||||||
|
)
|
||||||
|
|
||||||
let interfaceName =
|
let interfaceName =
|
||||||
let baseName = SynType.createLongIdent interfaceType.Name
|
let baseName = SynType.createLongIdent interfaceType.Name
|
||||||
|
|
||||||
@@ -174,7 +183,7 @@ module internal InterfaceMockGenerator =
|
|||||||
|
|
||||||
SynType.app' baseName generics
|
SynType.app' baseName generics
|
||||||
|
|
||||||
SynMemberDefn.Interface (interfaceName, Some range0, Some members, range0)
|
SynMemberDefn.Interface (interfaceName, Some range0, Some (members @ properties), range0)
|
||||||
|
|
||||||
let access =
|
let access =
|
||||||
match interfaceType.Accessibility, spec.IsInternal with
|
match interfaceType.Accessibility, spec.IsInternal with
|
||||||
@@ -248,6 +257,15 @@ module internal InterfaceMockGenerator =
|
|||||||
|> SynField.make
|
|> SynField.make
|
||||||
|> SynField.withDocString (mem.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
|> SynField.withDocString (mem.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
||||||
|
|
||||||
|
let constructProperty (prop : PropertyInfo) : SynField =
|
||||||
|
{
|
||||||
|
Attrs = []
|
||||||
|
Ident = Some prop.Identifier
|
||||||
|
Type = SynType.toFun [ SynType.unit ] prop.Type
|
||||||
|
}
|
||||||
|
|> SynField.make
|
||||||
|
|> SynField.withDocString (prop.XmlDoc |> Option.defaultValue PreXmlDoc.Empty)
|
||||||
|
|
||||||
let createRecord
|
let createRecord
|
||||||
(namespaceId : LongIdent)
|
(namespaceId : LongIdent)
|
||||||
(opens : SynOpenDeclTarget list)
|
(opens : SynOpenDeclTarget list)
|
||||||
@@ -255,7 +273,12 @@ module internal InterfaceMockGenerator =
|
|||||||
: SynModuleOrNamespace
|
: SynModuleOrNamespace
|
||||||
=
|
=
|
||||||
let interfaceType = AstHelper.parseInterface interfaceType
|
let interfaceType = AstHelper.parseInterface interfaceType
|
||||||
let fields = interfaceType.Members |> List.map constructMember
|
|
||||||
|
let fields =
|
||||||
|
interfaceType.Members
|
||||||
|
|> List.map constructMember
|
||||||
|
|> List.append (interfaceType.Properties |> List.map constructProperty)
|
||||||
|
|
||||||
let docString = PreXmlDoc.create "Mock record type for an interface"
|
let docString = PreXmlDoc.create "Mock record type for an interface"
|
||||||
|
|
||||||
let name =
|
let name =
|
||||||
|
Reference in New Issue
Block a user