Permalink
Browse files

Started working on Stubs.. still need to improve .Utils.GetDefaultValue

  • Loading branch information...
vincentparrett committed Sep 8, 2013
1 parent 7b1cd61 commit 00b110a78f86d35a80efafee04478c1208cc5ff6
@@ -58,7 +58,7 @@ TProxyVirtualInterface = class(TVirtualInterface)
function Proxy : T;override;
function CastAs<I: IInterface> : I;
public
constructor Create;override;
constructor Create(const AIsStubOnly : boolean);override;
destructor Destroy;override;
end;
@@ -79,11 +79,11 @@ function TInterfaceProxy<T>.CastAs<I>: I;
FVirtualInterfaces.Add(GetTypeData(TypeInfo(I)).Guid, virtualProxy);
end;
constructor TInterfaceProxy<T>.Create;
constructor TInterfaceProxy<T>.Create(const AIsStubOnly : boolean);
var
virtualProxy : TProxyVirtualInterface;
begin
inherited;
inherited Create(AIsStubOnly);
FVirtualInterfaces := TDictionary<TGUID, TProxyVirtualInterface>.Create;
@@ -40,10 +40,11 @@ interface
type
TMethodData = class(TInterfacedObject,IMethodData)
private
FMethodName : string;
FBehaviors : TList<IBehavior>;
FReturnDefault : TValue;
FExpectations : TList<IExpectation>;
FMethodName : string;
FBehaviors : TList<IBehavior>;
FReturnDefault : TValue;
FExpectations : TList<IExpectation>;
FIsStub : boolean;
protected
//Behaviors
@@ -86,7 +87,7 @@ TMethodData = class(TInterfacedObject,IMethodData)
function Verify(var report : string) : boolean;
public
constructor Create(const AMethodName : string);
constructor Create(const AMethodName : string; const AIsStub : boolean);
destructor Destroy;override;
end;
@@ -97,6 +98,7 @@ ENotImplemented = class(Exception);
implementation
uses
Delphi.Mocks.Utils,
Delphi.Mocks.Behavior,
Delphi.Mocks.Expectation;
@@ -105,12 +107,13 @@ implementation
{ TMethodData }
constructor TMethodData.Create(const AMethodName : string);
constructor TMethodData.Create(const AMethodName : string; const AIsStub : boolean);
begin
FMethodName := AMethodName;
FBehaviors := TList<IBehavior>.Create;
FExpectations := TList<IExpectation>.Create;
FReturnDefault := TValue.Empty;
FIsStub := AIsStub;
end;
destructor TMethodData.Destroy;
@@ -413,7 +416,10 @@ procedure TMethodData.RecordHit(const Args: TArray<TValue>; const returnType : T
else
begin
if (returnType <> nil) and (FReturnDefault.IsEmpty) then
raise EMockException.Create('No default return value defined for method ' + FMethodName);
if FIsStub then
result := GetDefaultValue(returnType)
else
raise EMockException.Create('No default return value defined for method ' + FMethodName);
returnVal := FReturnDefault;
end;
if returnType <> nil then
@@ -45,7 +45,7 @@ TObjectProxy<T> = class(TBaseProxy<T>)
procedure DoBefore(Instance: TObject; Method: TRttiMethod; const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue);
function Proxy : T;override;
public
constructor Create;override;
constructor Create(const AIsStubOnly : boolean);override;
destructor Destroy;override;
end;
@@ -57,14 +57,14 @@ implementation
{ TObjectProxy<T> }
constructor TObjectProxy<T>.Create;
constructor TObjectProxy<T>.Create(const AIsStubOnly : boolean);
var
ctx : TRttiContext;
rType : TRttiType;
ctor : TRttiMethod;
instance : TValue;
begin
inherited;
inherited Create(AIsStubOnly);
ctx := TRttiContext.Create;
rType := ctx.GetType(TypeInfo(T));
if rType = nil then
View
@@ -40,11 +40,11 @@ interface
TSetupMode = (None, Behavior, Expectation);
TBaseProxy<T> = class(TInterfacedObject, IInterface, IProxy<T>, ISetup<T>, IExpect<T>, IVerify)
TBaseProxy<T> = class(TInterfacedObject, IInterface, IProxy<T>, IStubProxy<T>, IMockSetup<T>, IStubSetup<T>, IExpect<T>, IVerify)
private
FMethodData : TDictionary<string,IMethodData>;
FMethodData : TDictionary<string,IMethodData>;
FBehaviorMustBeDefined : Boolean;
FSetupMode : TSetupMode;
FSetupMode : TSetupMode;
//behavior setup
FNextBehavior : TBehaviorType;
FReturnValue : TValue;
@@ -55,16 +55,23 @@ TBaseProxy<T> = class(TInterfacedObject, IInterface, IProxy<T>, ISetup<T>, IEx
FNextExpectation : TExpectationType;
FTimes : Cardinal;
FBetween : array[0..1] of Cardinal;
FIsStubOnly : boolean;
protected
function QueryInterface(const IID: TGUID; out Obj): HRESULT;virtual; stdcall;
function InternalQueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
//IProxy<T>
function Setup : ISetup<T>;
function MockSetup : IMockSetup<T>;
function StubSetup : IStubSetup<T>;
function IProxy<T>.Setup = MockSetup;
function IStubProxy<T>.Setup = StubSetup;
function Proxy : T;virtual;abstract;
//ISetup<T>
function GetBehaviorMustBeDefined : boolean;
procedure SetBehaviorMustBeDefined(const value : boolean);
@@ -117,7 +124,7 @@ TBaseProxy<T> = class(TInterfacedObject, IInterface, IProxy<T>, ISetup<T>, IEx
function After(const AMethodName : string) : IWhen<T>;overload;
procedure After(const AMethodName : string; const AAfterMethodName : string);overload;
public
constructor Create;virtual;
constructor Create(const AIsStubOnly : boolean);virtual;
destructor Destroy;override;
end;
@@ -252,11 +259,12 @@ procedure TBaseProxy<T>.ClearSetupState;
FNextFunc := nil;
end;
constructor TBaseProxy<T>.Create;
constructor TBaseProxy<T>.Create(const AIsStubOnly : boolean);
begin
FSetupMode := TSetupMode.None;
FBehaviorMustBeDefined := False;
FMethodData := TDictionary<string,IMethodData>.Create;
FIsStubOnly := AIsStubOnly;
end;
destructor TBaseProxy<T>.Destroy;
@@ -370,7 +378,7 @@ function TBaseProxy<T>.GetMethodData(const AMethodName: string): IMethodData;
if FMethodData.TryGetValue(methodName,Result) then
exit;
Result := TMethodData.Create(AMethodName);
Result := TMethodData.Create(AMethodName,FIsStubOnly);
FMethodData.Add(methodName,Result);
end;
@@ -431,7 +439,12 @@ procedure TBaseProxy<T>.SetBehaviorMustBeDefined(const value: boolean);
end;
function TBaseProxy<T>.Setup: ISetup<T>;
function TBaseProxy<T>.StubSetup: IStubSetup<T>;
begin
result := Self;
end;
function TBaseProxy<T>.MockSetup: IMockSetup<T>;
begin
result := Self;
end;
View
@@ -29,18 +29,21 @@
interface
uses
TypInfo;
TypInfo,
RTTI;
function CheckInterfaceHasRTTI(const info : PTypeInfo) : boolean;
function CheckClassHasRTTI(const info: PTypeInfo): boolean;
function GetVirtualMethodCount(AClass: TClass): Integer;
function GetDefaultValue(const rttiType : TRttiType) : TValue;
implementation
uses
SysUtils,
RTTI;
Variants,
SysUtils;
function CheckInterfaceHasRTTI(const info : PTypeInfo) : boolean;
var
@@ -81,6 +84,35 @@ function GetVirtualMethodCount(AClass: TClass): Integer;
(Integer(AClass) + vmtParent) - SizeOf(Pointer)) div SizeOf(Pointer);
end;
//TODO : There must be a better way than this. How does Default(X) work? Couldn't find the implementation.
function GetDefaultValue(const rttiType : TRttiType) : TValue;
begin
result := TValue.Empty;
case rttiType.TypeKind of
tkUnknown: ;
tkInteger: result := TValue.From<integer>(0);
tkChar: result := TValue.From<Char>(#0);
tkEnumeration: result := TValue.FromOrdinal(rttiType.Handle,rttiType.AsOrdinal.MinValue);
tkFloat: result := TValue.From<Extended>(0);
tkString: result := TValue.From<string>('');
tkSet: result := TValue.FromOrdinal(rttiType.Handle,rttiType.AsOrdinal.MinValue);
tkClass: result := TValue.From<TObject>(nil);
tkMethod: result := TValue.From<TObject>(nil);
tkWChar: result := TValue.From<WideChar>(#0);
tkLString: result := TValue.From<string>('');
tkWString: result := TValue.From<string>('');
tkVariant: result := TValue.From<Variant>(null);
tkArray: ;
tkRecord: ;
tkInterface: result := TValue.From<IInterface>(nil);
tkInt64: result := TValue.FromOrdinal(rttiType.Handle,0);
tkDynArray: ;
tkUString: result := TValue.From<string>('');
tkClassRef: result := TValue.From<TClass>(nil);
tkPointer: result := TValue.From<Pointer>(nil);
tkProcedure: result := TValue.From<Pointer>(nil);
end;
end;
View
@@ -54,15 +54,27 @@
{$UNDEF UNSUPPORTED_COMPILER_VERSION}
{$ENDIF VER240}
{$IFDEF VER250} // RAD Studio XE3
{$IFDEF VER250} // RAD Studio XE4
{$DEFINE DELPHI_2010_UP}
{$DEFINE DELPHI_XE_UP}
{$DEFINE DELPHI_XE2_UP}
{$DEFINE DELPHI_XE3_UP}
{$DEFINE DELPHI_XE4}
{$DEFINE DELPHI_XE4_UP}
{$UNDEF UNSUPPORTED_COMPILER_VERSION}
{$ENDIF VER240}
{$ENDIF VER250}
{$IFDEF VER260} // RAD Studio XE4
{$DEFINE DELPHI_2010_UP}
{$DEFINE DELPHI_XE_UP}
{$DEFINE DELPHI_XE2_UP}
{$DEFINE DELPHI_XE3_UP}
{$DEFINE DELPHI_XE4}
{$DEFINE DELPHI_XE4_UP}
{$DEFINE DELPHI_XE5}
{$DEFINE DELPHI_XE5_UP}
{$UNDEF UNSUPPORTED_COMPILER_VERSION}
{$ENDIF VER260}
{$IFDEF UNSUPPORTED_COMPILER_VERSION}
Oops, something went wrong.

0 comments on commit 00b110a

Please sign in to comment.